| File: Instance\ImmutableProjectCollections\LazyStringValuedList.cs | Web Access |
| Project: src\msbuild\src\Build\Microsoft.Build.csproj (Microsoft.Build) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections; using System.Collections.Generic; using Microsoft.Build.Collections; using Microsoft.Build.ObjectModelRemoting; using Microsoft.Build.Shared; namespace Microsoft.Build.Instance { /// <summary> /// Implements a lazy-initialized, immutable list of strings that can be used to represent project imports in the ProjectInstance /// when it is created from an immutable project link. /// It is to reduce memory usage to create and hold the list until a consumer actually accesses it. /// </summary> internal class LazyStringValuedList : IList<string>, IReadOnlyList<string> { private readonly LockType _syncLock = new(); private readonly ProjectLink _immutableProject; private readonly Func<ProjectLink, List<string>> _getStringValues; private List<string>? _items; public LazyStringValuedList(ProjectLink immutableProject, Func<ProjectLink, List<string>> getStringValues) { _immutableProject = immutableProject; _getStringValues = getStringValues; } public string this[int index] { set => throw new NotSupportedException(); get => EnsureListInitialized()[index]; } public int Count => EnsureListInitialized().Count; public bool IsReadOnly => true; public void Add(string item) => throw new NotSupportedException(); public void Clear() => throw new NotSupportedException(); public void Insert(int index, string item) => throw new NotSupportedException(); public bool Remove(string item) => throw new NotSupportedException(); public void RemoveAt(int index) => throw new NotSupportedException(); public bool Contains(string item) => IndexOf(item) >= 0; public void CopyTo(string[] array, int arrayIndex) { var items = EnsureListInitialized(); ErrorUtilities.VerifyCollectionCopyToArguments(array, arrayIndex, items.Count); items.CopyTo(array, arrayIndex); } public IEnumerator<string> GetEnumerator() => EnsureListInitialized().GetEnumerator(); public int IndexOf(string item) { List<string> itemList = EnsureListInitialized(); for (int i = 0; i < itemList.Count; ++i) { string stringValue = itemList[i]; if (MSBuildNameIgnoreCaseComparer.Default.Equals(stringValue, item)) { return i; } } return -1; } IEnumerator IEnumerable.GetEnumerator() => EnsureListInitialized().GetEnumerator(); private List<string> EnsureListInitialized() { if (_items == null) { lock (_syncLock) { if (_items == null) { _items = _getStringValues(_immutableProject); } } } return _items; } } }