//****************************************************************************************************** // ImmutableList`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; namespace GSF.Immutable { /// /// A list that can be modified until is set to true. Once this occurs, /// the list itself can no longer be modified. Remember, this does not cause objects contained in this class to be Immutable /// unless they implement . /// /// public class ImmutableList : ImmutableObjectBase>, IList { private readonly bool m_isISupportsReadonlyType; private List m_list; private Func m_formatter; /// /// Creates a new . /// /// Allows items to be formatted when inserted into a list. public ImmutableList(Func formatter = null) { m_formatter = formatter; m_isISupportsReadonlyType = typeof(IImmutableObject).IsAssignableFrom(typeof(T)); m_list = new List(); } /// /// Creates a new . /// public ImmutableList(int capacity, Func formatter = null) { m_formatter = formatter; m_isISupportsReadonlyType = typeof(IImmutableObject).IsAssignableFrom(typeof(T)); m_list = new List(capacity); } /// Returns an enumerator that iterates through the collection. /// A that can be used to iterate through the collection. /// 1 public IEnumerator GetEnumerator() { return m_list.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_list).GetEnumerator(); } /// Adds an item to the . /// The object to add to the . /// The is read-only. public void Add(T item) { TestForEditable(); if (m_formatter == null) { m_list.Add(item); } else { m_list.Add(m_formatter(item)); } } /// /// Adds the elements of the specified collection to the end of the . /// /// The collection whose elements should be added to the end of the . /// The collection itself cannot be null, but it can contain elements that are null public void AddRange(IEnumerable collection) { TestForEditable(); if (m_formatter != null) { foreach (var item in collection) { m_list.Add(m_formatter(item)); } return; } m_list.AddRange(collection); } /// Removes all items from the collection. public void Clear() { TestForEditable(); m_list.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 m_list.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) { m_list.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 . public bool Remove(T item) { TestForEditable(); return m_list.Remove(item); } /// Gets the number of elements contained in the . /// The number of elements contained in the . public int Count { get { return m_list.Count; } } /// /// Requests that member fields be set to readonly. /// protected override void SetMembersAsReadOnly() { if (m_isISupportsReadonlyType) { for (int x = 0; x < m_list.Count; x++) { var item = ((IImmutableObject)m_list[x]); if (item != null) { item.IsReadOnly = true; } } } } /// /// Request that member fields be cloned and marked as editable. /// protected override void CloneMembersAsEditable() { if (m_isISupportsReadonlyType) { List oldList = m_list; m_list = new List(oldList.Count); for (int x = 0; x < oldList.Count; x++) { var item = ((IImmutableObject)oldList[x]); if (item == null) { m_list.Add(default(T)); } else { m_list.Add((T)item.CloneEditable()); } } } else { m_list = new List(m_list); } } /// 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 m_list.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 . public void Insert(int index, T item) { TestForEditable(); if (m_formatter == null) { m_list.Insert(index, item); } else { m_list.Insert(index, m_formatter(item)); } } /// Removes the item at the specified index. /// The zero-based index of the item to remove. public void RemoveAt(int index) { TestForEditable(); m_list.RemoveAt(index); } /// 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. public T this[int index] { get { return m_list[index]; } set { TestForEditable(); if (m_formatter == null) { m_list[index] = value; } else { m_list[index] = m_formatter(value); } } } } }