|
// 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();
}
}
}
}
}
|