| File: ObjectCollection.cs | Web Access |
| Project: src\aspnetcore\src\Http\Headers\src\Microsoft.Net.Http.Headers.csproj (Microsoft.Net.Http.Headers) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.ObjectModel; namespace Microsoft.Net.Http.Headers; // List<T> allows 'null' values to be added. This is not what we want so we use a custom Collection<T> derived // type to throw if 'null' gets added. Collection<T> internally uses List<T> which comes at some cost. In addition // Collection<T>.Add() calls List<T>.InsertItem() which is an O(n) operation (compared to O(1) for List<T>.Add()). // This type is only used for very small collections (1-2 items) to keep the impact of using Collection<T> small. internal sealed class ObjectCollection<T> : Collection<T> { internal static readonly Action<T> DefaultValidator = CheckNotNull; internal static readonly ObjectCollection<T> EmptyReadOnlyCollection = new ObjectCollection<T>(DefaultValidator, isReadOnly: true); private readonly Action<T> _validator; // We need to create a 'read-only' inner list for Collection<T> to do the right // thing. private static IList<T> CreateInnerList(bool isReadOnly, IEnumerable<T>? other = null) { var list = other == null ? new List<T>() : new List<T>(other); if (isReadOnly) { return new ReadOnlyCollection<T>(list); } else { return list; } } public ObjectCollection() : this(DefaultValidator) { } public ObjectCollection(Action<T> validator, bool isReadOnly = false) : base(CreateInnerList(isReadOnly)) { _validator = validator; } public ObjectCollection(IEnumerable<T> other, bool isReadOnly = false) : base(CreateInnerList(isReadOnly, other)) { _validator = DefaultValidator; foreach (T item in Items) { _validator(item); } } public bool IsReadOnly => ((ICollection<T>)this).IsReadOnly; protected override void InsertItem(int index, T item) { _validator(item); base.InsertItem(index, item); } protected override void SetItem(int index, T item) { _validator(item); base.SetItem(index, item); } private static void CheckNotNull(T item) { // null values cannot be added to the collection. if (item == null) { throw new ArgumentNullException(nameof(item)); } } }