//******************************************************************************************************
// ListCollection.cs - Gbtc
//
// Copyright © 2014, 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 MIT License (MIT), 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/MIT
//
// 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:
// ----------------------------------------------------------------------------------------------------
// 05/09/2014 - Steven E. Chisholm
// Generated original version of source code.
//
//******************************************************************************************************
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace GSF.Collections
{
///
/// A faster and functionally equivalent implementation of
///
/// The type of the element in the collection
///
///
/// is based upon an . This means any simple call
/// to the class is a function call that cannot be in-lined. This implementation forces the underlying
/// item to be and shadows many of the methods to call
/// instead of .
///
///
/// Since this class references the same underlying object, it can be
/// successfully implemented as a or casted it its underlying type
/// .
///
///
/// Profiling this class yield a ForEach loop and For loop that executes between
/// 2-4 times faster than . This depends on the number of items in the
/// list. The fewer the faster. Other operations such as Add/Insert/Remove are closer to 50% faster.
/// Count is now in-lined (~20 times faster).
///
///
/// This performance is negated if accessing this class via the IList interface. When possible, use
/// only strongly typed names.
///
///
// Note that explicit re-declaration of interfaces is required here because of shadowed methods
public class ListCollection : Collection, IList, IList, IReadOnlyList
{
#region [ Members ]
// Fields
private readonly List m_list; // Strongly typed reference to Items collection
#endregion
#region [ Constructors ]
///
/// Creates a
///
/// a list to wrap this class around.
public ListCollection(List list)
: base(list)
{
m_list = (List)base.Items;
}
///
/// Creates a
///
public ListCollection()
: this(new List())
{
}
#endregion
#region [ Properties ]
///
/// Gets the number of elements contained in the .
///
///
/// The number of elements contained in the .
///
public new int Count
{
get
{
return m_list.Count;
}
}
///
/// 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 new T this[int index]
{
get
{
return m_list[index];
}
set
{
if (index < 0 || index >= m_list.Count)
ThrowOutOfRangeException();
SetItem(index, value);
}
}
///
/// Gets a wrapper around the .
///
///
/// A wrapper around the .
///
protected new List Items
{
get
{
return m_list;
}
}
#endregion
#region [ Methods ]
///
/// Adds an item to the .
///
/// The object to add to the .
/// The is read-only.
public new void Add(T item)
{
InsertItem(m_list.Count, item);
}
///
/// Removes all items from the .
///
/// The is read-only.
public new void Clear()
{
ClearItems();
}
///
/// Removes all elements from the .
///
protected override void ClearItems()
{
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 new 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.
///
/// is null.
/// is less than 0.
/// The number of elements in the source is greater than the available space from to the end of the destination .
public new void CopyTo(T[] array, int index)
{
m_list.CopyTo(array, index);
}
///
/// Returns an enumerator that iterates through the .
///
///
/// An for the .
///
public new List.Enumerator GetEnumerator()
{
return m_list.GetEnumerator();
}
///
/// 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 new 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 .
/// is not a valid index in the .
/// The is read-only.
public new void Insert(int index, T item)
{
if (index < 0 || index > m_list.Count)
ThrowOutOfRangeException();
InsertItem(index, item);
}
///
/// Inserts an element into the at the specified index.
///
/// The zero-based index at which should be inserted.
/// The object to insert. The value can be null for reference types.
/// is less than zero.-or- is greater than .
protected override void InsertItem(int index, T item)
{
m_list.Insert(index, item);
}
///
/// 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 .
/// The is read-only.
public new bool Remove(T item)
{
int index = m_list.IndexOf(item);
if (index < 0)
return false;
RemoveItem(index);
return true;
}
///
/// Removes the element at the specified index of the .
///
/// The zero-based index of the element to remove.
/// is less than zero.-or- is equal to or greater than .
public new void RemoveAt(int index)
{
if (index < 0 || index >= m_list.Count)
ThrowOutOfRangeException();
RemoveItem(index);
}
///
/// Removes the element at the specified index of the .
///
/// The zero-based index of the element to remove.
/// is less than zero.-or- is equal to or greater than .
protected override void RemoveItem(int index)
{
m_list.RemoveAt(index);
}
///
/// Replaces the element at the specified index.
///
/// The zero-based index of the element to replace.
/// The new value for the element at the specified index. The value can be null for reference types.
/// is less than zero.-or- is greater than .
protected override void SetItem(int index, T item)
{
m_list[index] = item;
}
private static void ThrowOutOfRangeException()
{
// ReSharper disable once NotResolvedInText
throw new ArgumentOutOfRangeException("index");
}
#endregion
}
}