//****************************************************************************************************** // ImmutableArray`1.cs - Gbtc // // Copyright © 2016, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/eclipse-1.0.php // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 10/24/2016 - Steven E. Chisholm // Generated original version of source code. // // //****************************************************************************************************** using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace GSF.Immutable { /// /// A array that can be modified until is set to true. Once this occurs, /// the array itself can no longer be modified. Remember, this does not cause objects contained in this class to be Immutable /// unless they implement . /// /// public sealed class ImmutableArray : ImmutableObjectBase>, IList { private readonly bool m_isISupportsReadonlyType; private T[] m_array; private Func m_formatter; /// /// Creates a new . /// public ImmutableArray(int size, Func formatter = null) { m_formatter = formatter; m_isISupportsReadonlyType = typeof(IImmutableObject).IsAssignableFrom(typeof(T)); m_array = new T[size]; } /// /// Creates a new . /// public ImmutableArray(IEnumerable items, Func formatter = null) { m_formatter = formatter; m_isISupportsReadonlyType = typeof(IImmutableObject).IsAssignableFrom(typeof(T)); m_array = items.ToArray(); if (formatter != null) { for (int x = 0; x < m_array.Length; x++) { m_array[x] = formatter(m_array[x]); } } } /// Returns an enumerator that iterates through the collection. /// A that can be used to iterate through the collection. /// 1 public IEnumerator GetEnumerator() { return ((IList)m_array).GetEnumerator(); } /// Returns an enumerator that iterates through a collection. /// An object that can be used to iterate through the collection. /// 2 IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)m_array).GetEnumerator(); } /// Adds an item to the . /// The object to add to the . /// The is read-only. void ICollection.Add(T item) { throw new NotSupportedException("Cannot add to an array"); } /// Removes all items from the . /// The is read-only. void ICollection.Clear() { TestForEditable(); ((IList)m_array).Clear(); } /// Determines whether the contains a specific value. /// true if is found in the ; otherwise, false. /// The object to locate in the . public bool Contains(T item) { return ((IList)m_array).Contains(item); } /// Copies the elements of the to an , starting at a particular index. /// The one-dimensional that is the destination of the elements copied from . The must have zero-based indexing. /// The zero-based index in at which copying begins. public void CopyTo(T[] array, int arrayIndex) { ((IList)m_array).CopyTo(array, arrayIndex); } /// Removes the first occurrence of a specific object from the . /// true if was successfully removed from the ; otherwise, false. This method also returns false if is not found in the original . /// The object to remove from the . bool ICollection.Remove(T item) { throw new NotSupportedException("Cannot remove from an array"); } /// Gets the number of elements contained in the . /// The number of elements contained in the . public int Count { get { return m_array.Length; } } /// /// Sets members as readonly /// protected override void SetMembersAsReadOnly() { if (m_isISupportsReadonlyType) { for (int x = 0; x < m_array.Length; x++) { var item = ((IImmutableObject)m_array[x]); if (item != null) { item.IsReadOnly = true; } } } } /// /// CloneMembersAsEditable /// protected override void CloneMembersAsEditable() { m_array = (T[])m_array.Clone(); if (m_isISupportsReadonlyType) { for (int x = 0; x < m_array.Length; x++) { var item = ((IImmutableObject)m_array[x]); if (item != null) { m_array[x] = (T)item.CloneEditable(); } } } } /// Determines the index of a specific item in the . /// The index of if found in the list; otherwise, -1. /// The object to locate in the . public int IndexOf(T item) { return ((IList)m_array).IndexOf(item); } /// Inserts an item to the at the specified index. /// The zero-based index at which should be inserted. /// The object to insert into the . /// /// is not a valid index in the . /// The is read-only. void IList.Insert(int index, T item) { throw new NotSupportedException("Cannot remove from an array"); } /// Removes the item at the specified index. /// The zero-based index of the item to remove. /// /// is not a valid index in the . /// The is read-only. void IList.RemoveAt(int index) { throw new NotSupportedException("Cannot remove from an array"); } /// Gets or sets the element at the specified index. /// The element at the specified index. /// The zero-based index of the element to get or set. /// /// is not a valid index in the . /// The property is set and the is read-only. public T this[int index] { get { return m_array[index]; } set { TestForEditable(); if (m_formatter == null) { m_array[index] = value; } else { m_array[index] = m_formatter(value); } } } } }