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