| File: Language\Syntax\SpecializedCollections.cs | Web Access |
| Project: src\roslyn\src\Razor\src\Compiler\Microsoft.CodeAnalysis.Razor.Compiler\src\Microsoft.CodeAnalysis.Razor.Compiler.csproj (Microsoft.CodeAnalysis.Razor.Compiler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. #nullable disable using System; using System.Collections; using System.Collections.Generic; namespace Microsoft.AspNetCore.Razor.Language.Syntax; internal static class SpecializedCollections { public static IEnumerator<T> EmptyEnumerator<T>() { return Empty.Enumerator<T>.Instance; } public static IEnumerable<T> EmptyEnumerable<T>() { return Empty.List<T>.Instance; } public static ICollection<T> EmptyCollection<T>() { return Empty.List<T>.Instance; } public static IList<T> EmptyList<T>() { return Empty.List<T>.Instance; } public static IReadOnlyList<T> EmptyReadOnlyList<T>() { return Empty.List<T>.Instance; } private class Empty { internal class Enumerator<T> : Enumerator, IEnumerator<T> { public static new readonly IEnumerator<T> Instance = new Enumerator<T>(); protected Enumerator() { } public new T Current => throw new InvalidOperationException(); public void Dispose() { } } internal class Enumerator : IEnumerator { public static readonly IEnumerator Instance = new Enumerator(); protected Enumerator() { } public object Current => throw new InvalidOperationException(); public bool MoveNext() { return false; } public void Reset() { throw new InvalidOperationException(); } } internal class Enumerable<T> : IEnumerable<T> { // PERF: cache the instance of enumerator. // accessing a generic static field is kinda slow from here, // but since empty enumerables are singletons, there is no harm in having // one extra instance field private readonly IEnumerator<T> _enumerator = Enumerator<T>.Instance; public IEnumerator<T> GetEnumerator() { return _enumerator; } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } } internal class Collection<T> : Enumerable<T>, ICollection<T> { public static readonly ICollection<T> Instance = new Collection<T>(); protected Collection() { } public void Add(T item) { throw new NotSupportedException(); } public void Clear() { throw new NotSupportedException(); } public bool Contains(T item) { return false; } public void CopyTo(T[] array, int arrayIndex) { } public int Count => 0; public bool IsReadOnly => true; public bool Remove(T item) { throw new NotSupportedException(); } } internal class List<T> : Collection<T>, IList<T>, IReadOnlyList<T> { public static new readonly List<T> Instance = new List<T>(); protected List() { } public int IndexOf(T item) { return -1; } public void Insert(int index, T item) { throw new NotSupportedException(); } public void RemoveAt(int index) { throw new NotSupportedException(); } public T this[int index] { get { throw new ArgumentOutOfRangeException(nameof(index)); } set { throw new NotSupportedException(); } } } } }