| File: System\Xml\Xsl\ListBase.cs | Web Access |
| Project: src\runtime\src\libraries\System.Private.Xml\src\System.Private.Xml.csproj (System.Private.Xml) |
// 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.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Text; using System.Xml; using System.Xml.Schema; namespace System.Xml.Xsl { /// <summary> /// Implementation of read-only IList and IList{T} interfaces. Derived classes can inherit from /// this class and implement only two methods, Count and Item, rather than the entire IList interface. /// </summary> internal abstract class ListBase<T> : IList<T>, System.Collections.IList { //----------------------------------------------- // Abstract IList methods that must be // implemented by derived classes //----------------------------------------------- public abstract int Count { get; } public abstract T this[int index] { get; set; } //----------------------------------------------- // Implemented by base class -- accessible on // ListBase //----------------------------------------------- public virtual bool Contains(T value) { return IndexOf(value) != -1; } public virtual int IndexOf(T value) { for (int i = 0; i < Count; i++) if (value!.Equals(this[i])) return i; return -1; } public virtual void CopyTo(T[] array, int index) { for (int i = 0; i < Count; i++) array[index + i] = this[i]; } public virtual IListEnumerator<T> GetEnumerator() { return new IListEnumerator<T>(this); } public virtual bool IsFixedSize { get { return true; } } public virtual bool IsReadOnly { get { return true; } } public virtual void Add(T value) { Insert(Count, value); } public virtual void Insert(int index, T value) { throw new NotSupportedException(); } public virtual bool Remove(T value) { int index = IndexOf(value); if (index >= 0) { RemoveAt(index); return true; } return false; } public virtual void RemoveAt(int index) { throw new NotSupportedException(); } public virtual void Clear() { for (int index = Count - 1; index >= 0; index--) RemoveAt(index); } //----------------------------------------------- // Implemented by base class -- only accessible // after casting to IList //----------------------------------------------- IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new IListEnumerator<T>(this); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return new IListEnumerator<T>(this); } bool System.Collections.ICollection.IsSynchronized { get { return IsReadOnly; } } object System.Collections.ICollection.SyncRoot { get { return this; } } void System.Collections.ICollection.CopyTo(Array array, int index) { for (int i = 0; i < Count; i++) array.SetValue(this[i], index); } object? System.Collections.IList.this[int index] { get { return this[index]; } set { if (!IsCompatibleType(value!.GetType())) throw new ArgumentException(SR.Arg_IncompatibleParamType, nameof(value)); this[index] = (T)value; } } int System.Collections.IList.Add(object? value) { if (!IsCompatibleType(value!.GetType())) throw new ArgumentException(SR.Arg_IncompatibleParamType, nameof(value)); Add((T)value); return Count - 1; } void System.Collections.IList.Clear() { Clear(); } bool System.Collections.IList.Contains(object? value) { if (!IsCompatibleType(value!.GetType())) return false; return Contains((T)value); } int System.Collections.IList.IndexOf(object? value) { if (!IsCompatibleType(value!.GetType())) return -1; return IndexOf((T)value); } void System.Collections.IList.Insert(int index, object? value) { if (!IsCompatibleType(value!.GetType())) throw new ArgumentException(SR.Arg_IncompatibleParamType, nameof(value)); Insert(index, (T)value); } void System.Collections.IList.Remove(object? value) { if (IsCompatibleType(value!.GetType())) { Remove((T)value); } } //----------------------------------------------- // Helper methods and classes //----------------------------------------------- private static bool IsCompatibleType(object? value) { if ((value == null && !typeof(T).IsValueType) || (value is T)) return true; return false; } } /// <summary> /// Implementation of IEnumerator{T} and IEnumerator over an IList{T}. /// </summary> internal struct IListEnumerator<T> : IEnumerator<T>, System.Collections.IEnumerator { private readonly IList<T> _sequence; private int _index; private T _current; /// <summary> /// Constructor. /// </summary> public IListEnumerator(IList<T> sequence) { _sequence = sequence; _index = 0; _current = default(T)!; } /// <summary> /// No-op. /// </summary> public void Dispose() { } /// <summary> /// Return current item. Return default value if before first item or after last item in the list. /// </summary> public T Current { get { return _current; } } /// <summary> /// Return current item. Throw exception if before first item or after last item in the list. /// </summary> object System.Collections.IEnumerator.Current { get { if (_index == 0) throw new InvalidOperationException(SR.Format(SR.Sch_EnumNotStarted, string.Empty)); if (_index > _sequence.Count) throw new InvalidOperationException(SR.Format(SR.Sch_EnumFinished, string.Empty)); return _current!; } } /// <summary> /// Advance enumerator to next item in list. Return false if there are no more items. /// </summary> public bool MoveNext() { if (_index < _sequence.Count) { _current = _sequence[_index]; _index++; return true; } _current = default(T)!; return false; } /// <summary> /// Set the enumerator to its initial position, which is before the first item in the list. /// </summary> void System.Collections.IEnumerator.Reset() { _index = 0; _current = default(T)!; } } }