CSSortedList

来源:互联网 发布:突击英雄知乎 编辑:程序博客网 时间:2024/06/05 05:40

<%@ CodeTemplate Language="C#" TargetLanguage="C#" Description="Generates a strongly-typed collection of key-and-value pairs that are sorted by the keys and are accessible by key and by index." %>
<%@ Property Name="ClassNamespace" Type="System.String" Optional="True" Category="Context" Description="The namespace that the generated class will be a member of." %>
<%@ Property Name="KeyType" Type="System.String" Category="Context" Description="The type to use as a key in the collection." %>
<%@ Property Name="ItemType" Type="System.String" Category="Context" Description="The type to use as an item in the collection." %>
<%@ Property Name="ClassName" Type="System.String" Category="Context" Description="The name of the class to be generated." %>
<%@ Property Name="GenerateDocumentation" Type="System.Boolean" Default="True" Category="Options" Description="Whether or not to include class documentation." %>
<%@ Property Name="Accessibility" Type="AccessibilityEnum" Category="Options" Description="The accessibility of the class to be generated." %>
using System;
using System.Collections;

<% if (ClassNamespace != null && ClassNamespace.Length > 0) { %>
namespace <%= ClassNamespace %>
{
<% } %>
 <% if (GenerateDocumentation) { %>
 /// <summary>
 ///  Represents a strongly-typed collection of key-and-value pairs that are
 ///  sorted by the keys and are accessible by key and by index.
 /// </summary>
 /// <seealso cref="System.Collections.SortedList"/>
 <% } %>
 [Serializable]
 <%= GetAccessModifier(Accessibility) %> class <%= ClassName %> : IDictionary, ICloneable
 {
  #region Member Variables
  private const int DEFAULT_CAPACITY = 16;

  private <%= KeyType %>[] keys;
  private <%= ItemType %>[] values;
  private int count;
  [NonSerialized]
  private int version;
  private IComparer comparer;
  private KeyList keyList;
  private ValueList valueList;
  #endregion

  #region Constructors
  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Initializes a new instance of the <see cref="<%= ClassName %>"/> class that is empty,
  ///  has the default initial capacity and is sorted according to the <see cref="IComparable"/> interface
  ///  implemented by each key added to the <b><%= ClassName %></b>.
  /// </summary>
  <% } %>
  public <%= ClassName %>()
  {
   keys = new <%= KeyType %>[DEFAULT_CAPACITY];
   values = new <%= ItemType %>[DEFAULT_CAPACITY];
   comparer = Comparer.Default;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Initializes a new instance of the <see cref="<%= ClassName %>"/> class that is empty,
  ///  has the specified initial capacity and is sorted according to the <see cref="IComparable"/>
  ///  interface implemented by each key added to the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="capacity">The initial number of elements that the <see cref="<%= ClassName %>"/> can contain.</param>
  /// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is less than zero.</exception>
  <% } %>
  public <%= ClassName %>(int capacity)
  {
   if (capacity < 0)
    throw new ArgumentOutOfRangeException("capacity", capacity, "Initial capacity cannot be less than zero.");

   keys = new <%= KeyType %>[capacity];
   values = new <%= ItemType %>[capacity];
   comparer = Comparer.Default;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Initializes a new instance of the <see cref="<%= ClassName %>"/> class that is empty,
  ///  has the default initial capacity and is sorted according to the specified
  ///  <see cref="IComparer"/> interface.
  /// </summary>
  /// <param name="comparer">
  ///  <para>The <see cref="IComparer"/> implementation to use when comparing keys.</para>
  ///  <para>-or-</para>
  ///  <para>A null reference, to use the <see cref="IComparable"/> implementation of each key.</para>
  /// </param>
  <% } %>
  public <%= ClassName %>(IComparer comparer) : this()
  {
   if (comparer != null)
    this.comparer = comparer;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Initializes a new instance of the <see cref="<%= ClassName %>"/> class that is empty,
  ///  has the specified initial capacity and is sorted according to the specified
  ///  <see cref="IComparer"/> interface.
  /// </summary>
  /// <param name="comparer">
  ///  <para>The <see cref="IComparer"/> implementation to use when comparing keys.</para>
  ///  <para>-or-</para>
  ///  <para>A null reference, to use the <see cref="IComparable"/> implementation of each key.</para>
  /// </param>
  /// <param name="capacity">The initial number of elements that the <see cref="<%= ClassName %>"/> can contain.</param>
   /// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity"/> is less than zero.</exception>
  <% } %>
  public <%= ClassName %>(IComparer comparer, int capacity) : this(capacity)
  {
   if (comparer != null)
    this.comparer = comparer;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Initializes a new instance of the <see cref="<%= ClassName %>"/> class that contains
  ///  elements copied from the specified dictionary, has the same initial capacity as the
  ///  number of elements copied and is sorted according to the <see cref="IComparable"/> interface
  ///  implemented by each key.
  /// </summary>
  /// <param name="d">The <see cref="IDictionary"/> to copy to a new SortedList.</param>
  /// <exception cref="ArgumentNullException"><paramref name="d"/> is a null reference.</exception>
  /// <exception cref="InvalidCastException">
  ///  <para>One or more elements in <paramref name="d"/> do not implement the
  ///  <see cref="IComparable"/> interface.</para>
  ///  <para>-or-</para>
  ///  <para><pararef name="d"/> contains elements of a type not supported by <see cref="<%= ClassName %>"/>.</para>
  /// </exception>
  <% } %>
  public <%= ClassName %>(IDictionary d) : this(d, null) {}

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Initializes a new instance of the <see cref="<%= ClassName %>"/> class that contains
  ///  elements copied from the specified dictionary, has the same initial capacity as the
  ///  number of elements copied and is sorted according to the specified <see cref="IComparer"/> interface.
  /// </summary>
  /// <param name="d">The <see cref="IDictionary"/> to copy to a new SortedList.</param>
  /// <param name="comparer">
  ///  <para>The <see cref="IComparer"/> implementation to use when comparing keys.</para>
  ///  <para>-or-</para>
  ///  <para>A null reference, to use the <see cref="IComparable"/> implementation of each key.</para>
  /// </param>
  /// <exception cref="ArgumentNullException"><paramref name="d"/> is a null reference.</exception>
  /// <exception cref="InvalidCastException">
  ///  <para>One or more elements in <paramref name="d"/> do not implement the
  ///  <see cref="IComparable"/> interface.</para>
  ///  <para>-or-</para>
  ///  <para><pararef name="d"/> contains elements of a type not supported by <see cref="<%= ClassName %>"/>.</para>
  /// </exception>
  <% } %>
  public <%= ClassName %>(IDictionary d, IComparer comparer)
   : this(comparer, (d == null ? 0 : d.Count))
  {
   if (d == null)
    throw new ArgumentNullException("d", "The IDictionary cannot be null.");

   d.Keys.CopyTo(keys, 0);
   d.Values.CopyTo(values, 0);
   Array.Sort(this.keys, this.values, this.comparer);
   this.count = d.Count;
  }
  #endregion

  #region Properties
  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets and sets the value associated with a specific key in the <b><%= ClassName %></b>.
  /// </summary>
  /// <value>
  ///  The <see cref="<%= ItemType %>"/> associated with <paramref name="key"/> in the <see cref="<%= ClassName %>"/>,
  ///  if <paramref name="key"/> is found; otherwise, a <see cref="NullReferenceException"/> is thrown.
  /// </value>
  /// <remarks>
  ///  This property, unlike its equivalent in <see cref="System.Collections.SortedList"/>, does not return
  ///  null when a key cannot be found. The reason for this is that the strongly-typed sorted list
  ///  template this class is created from allows the value to be a value type (or struct), which cannot
  ///  be set to null. Instead, a <see cref="NullReferenceException"/> is thrown when a key cannot be found.
  ///  Callers must either catch this exception, or call the <see cref="<%= ClassName %>.Contains"/> method first to
  ///  see if the key exists.
  /// </remarks>
  /// <exception cref="ArgumentNullException">The <paramref name="key"/> is a null reference.</exception>
  /// <exception cref="ArgumentException">
  ///  Either the <paramref name="key"/> or the <paramref name="value"/> are not of a type supported by the <see cref="<%= ClassName %>"/>.
  /// </exception>
  /// <exception cref="NullReferenceException">
  ///  <paramref name="key"/> is not found in the <see cref="<%= ClassName %>"/>.
  /// </exception>
  <% } %>
  object IDictionary.this[object key]
  {
   get
   {
    if (key == null)
     throw new ArgumentNullException("key", "The key cannot be null.");

    if (!(key is <%= KeyType %>))
     throw new ArgumentException("The key must be of type: " + typeof(<%= KeyType %>).FullName, "key");

    return this[(<%= KeyType %>)key];
   }
   set
   {
    if (key == null)
     throw new ArgumentNullException("key", "The key cannot be null.");

    if (!(key is <%= KeyType %>))
     throw new ArgumentException("The key must be of type: " + typeof(<%= KeyType %>).FullName, "key");

    if (!(value is <%= ItemType %>))
     throw new ArgumentException("The value must be of type: " + typeof(<%= ItemType %>).FullName, "value");

    this[(<%= KeyType %>)key] = (<%= ItemType %>)value;
   }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets and sets the value associated with a specific key in the <b><%= ClassName %></b>.
  /// </summary>
  /// <value>
  ///  The <see cref="<%= ItemType %>"/> associated with <paramref name="key"/> in the <see cref="<%= ClassName %>"/>,
  ///  if <paramref name="key"/> is found; otherwise, a <see cref="NullReferenceException"/> is thrown.
  /// </value>
  /// <remarks>
  ///  <para>This property, unlike its equivalent in <see cref="System.Collections.SortedList"/>, does not return
  ///  null when a key cannot be found. The reason for this is that the strongly-typed sorted list
  ///  template this class is created from allows the value to be a value type (or struct), which cannot
  ///  be set to null. Instead, a <see cref="NullReferenceException"/> is thrown when a key cannot be found.
  ///  Callers must either catch this exception, or call the <see cref="<%= ClassName %>.Contains"/> method first to
  ///  see if the key exists.</para>
  /// </remarks>
  /// <exception cref="ArgumentNullException">The <paramref name="key"/> is a null reference.</exception>
  /// <exception cref="NullReferenceException">
  ///  <paramref name="key"/> is not found in the <see cref="<%= ClassName %>"/>.
  /// </exception>
  <% } %>
  public virtual <%= ItemType %> this[<%= KeyType %> key]
  {
   get
   {
    int index = IndexOfKey(key);
    if (index >= 0)
     return values[index];

    throw new NullReferenceException("The specified key could not be found.");
   }
   set
   {
    if (Object.ReferenceEquals(key, null)) // avoids compiler error for null check on value type
     throw new ArgumentNullException("key", "The key cannot be null.");

    int index = Array.BinarySearch(keys, 0, count, key, comparer);
    if (index >= 0)
    {
     values[index] = value;
     version++;
     return;
    }

    Insert(~index, key, value);
   }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets or sets the capacity of the <b><%= ClassName %></b>.
  /// </summary>
  /// <value>The number of elements that the <see cref="<%= ClassName %>"/> can contain.</value>
  <% } %>
  public virtual int Capacity
  {
   get
   {
    return keys.Length;
   }
   set
   {
    if (value < count)
     value = count;

    if (value != keys.Length)
    {
     if (value > 0)
     {
      <%= KeyType %>[] newKeys = new <%= KeyType %>[value];
      <%= ItemType %>[] newValues = new <%= ItemType %>[value];

      if (count > 0)
      {
       Array.Copy(keys, 0, newKeys, 0, count);
       Array.Copy(values, 0, newValues, 0, count);
      }
      
      keys = newKeys;
      values = newValues;
     }
     else
     {
      keys = new <%= KeyType %>[DEFAULT_CAPACITY];
      values = new <%= ItemType %>[DEFAULT_CAPACITY];
     }
    }
   }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets the number of elements contained in the <b><%= ClassName %></b>.
  /// </summary>
  /// <value>The number of elements contained in the <see cref="<%= ClassName %>"/>.</value>
  <% } %>
  public virtual int Count
  {
   get
   {
    return this.count;
   }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets a value indicating whether the <b><%= ClassName %></b> has a fixed size.
  /// </summary>
  /// <value>
  ///  <b>true</b> if the <see cref="<%= ClassName %>"/> has a fixed size; otherwise, <b>false</b>.
  ///  The default is <b>false</b>.
  /// </value>
  <% } %>
  public virtual bool IsFixedSize
  {
   get { return false; }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets a value indicating whether the <b><%= ClassName %></b> is read-only.
  /// </summary>
  /// <value>
  ///  <b>true</b> if the <see cref="<%= ClassName %>"/> is read-only; otherwise, <b>false</b>.
  ///  The default is <b>false</b>.
  /// </value>
  <% } %>
  public virtual bool IsReadOnly
  {
   get { return false; }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets a value indicating whether access to the <b><%= ClassName %></b> is
  ///  synchronized (thread-safe).
  /// </summary>
  /// <value>
  ///  <b>true</b> if access to the the <see cref="<%= ClassName %>"/> is
  ///  synchronized (thread-safe); otherwise, <b>false</b>.
  ///  The default is <b>false</b>.
  /// </value>
  <% } %>
  public virtual bool IsSynchronized
  {
   get { return false; }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets the keys in the <b><%= ClassName %></b>.
  /// </summary>
  /// <value>An <see cref="ICollection"/> containing the keys in the <see cref="<%= ClassName %>"/>.</value>
  /// <remarks>
  ///  <para>The <see cref="ICollection"/> is a read-only view of the keys in the
  ///  <see cref="<%= ClassName %>"/>. Modifications made to the underlying <b><%= ClassName %></b>
  ///  are immediately reflected in the <b>ICollection</b>.</para>
  ///  <para>The elements of the <b>ICollection</b> are sorted in the same order as the keys
  ///  of the <b><%= ClassName %></b>.</para>
  ///  <para>Similar to <see cref="<%= ClassName %>.GetKeyList"/>, but returns an <b>ICollection</b>
  ///  instead of an <see cref="IList"/>.</para>
  /// </remarks>
  <% } %>
  public virtual ICollection Keys
  {
   get
   {
    return GetKeyList();
   }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets an object that can be used to synchronize access to the <b><%= ClassName %></b>.
  /// </summary>
  /// <value>An object that can be used to synchronize access to the <see cref="<%= ClassName %>"/>.</value>
  <% } %>
  public virtual object SyncRoot
  {
   get { return this; }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets the values in the <b><%= ClassName %></b>.
  /// </summary>
  /// <value>An <see cref="ICollection"/> containing the values in the <see cref="<%= ClassName %>"/>.</value>
  /// <remarks>
  ///  <para>The <see cref="ICollection"/> is a read-only view of the values in the
  ///  <see cref="<%= ClassName %>"/>. Modifications made to the underlying <b><%= ClassName %></b>
  ///  are immediately reflected in the <b>ICollection</b>.</para>
  ///  <para>The elements of the <b>ICollection</b> are sorted in the same order as the values
  ///  of the <b><%= ClassName %></b>.</para>
  ///  <para>Similar to <see cref="<%= ClassName %>.GetValueList"/>, but returns an <b>ICollection</b>
  ///  instead of an <see cref="IList"/>.</para>
  /// </remarks>
  <% } %>
  public virtual ICollection Values
  {
   get
   {
    return GetValueList();
   }
  }
  #endregion

  #region Public Methods
  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Adds an element with the specified key and value to the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="key">The key of the element to add.</param>
  /// <param name="value">The value of the element to add.</param>
  /// <exception cref="ArgumentNullException">The <paramref name="key"/> is a null reference.</exception>
  /// <exception cref="ArgumentException">
  ///  <para>An element with the specified <paramref name="key"/> already exists in the <see cref="<%= ClassName %>"/>.</para>
  ///  <para>-or-</para>
  ///  <para>Either the <paramref name="key"/> or the <paramref name="value"/> are not of a type supported by the <see cref="<%= ClassName %>"/>.</para>
  ///  <para>-or-</para>
  ///  <para>The <b><%= ClassName %></b> is set to use the <see cref="IComparable"/> interface,
  ///  and <paramref name="key"/> does not implement the <b>IComparable</b> interface.</para>
  /// </exception>
  /// <exception cref="InvalidOperationException">The comparer throws an exception.</exception>
  /// <exception cref="NotSupportedException">
  ///  <para>The <see cref="<%= ClassName %>"/> is read-only.</para>
  ///  <para>-or-</para>
  ///  <para>The <b><%= ClassName %></b> has a fixed size.</para>
  /// </exception>
  <% } %>
  void IDictionary.Add(object key, object value)
  {
   if (key == null)
    throw new ArgumentNullException("key", "The key cannot be null.");

   if (!(key is <%= KeyType %>))
    throw new ArgumentException("The key must be of type: " + typeof(<%= KeyType %>).FullName, "key");

   if (!(value is <%= ItemType %>))
    throw new ArgumentException("The value must be of type: " + typeof(<%= ItemType %>).FullName, "value");

   this.Add((<%= KeyType %>)key, (<%= ItemType %>)value);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Adds an element with the specified key and value to the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="key">The key of the element to add.</param>
  /// <param name="value">The value of the element to add.</param>
   /// <exception cref="ArgumentNullException">The <paramref name="key"/> is a null reference.</exception>
  /// <exception cref="ArgumentException">
  ///  <para>An element with the specified <paramref name="key"/> already exists in the <see cref="<%= ClassName %>"/>.</para>
  ///  <para>-or-</para>
  ///  <para>The <b><%= ClassName %></b> is set to use the <see cref="IComparable"/> interface,
  ///  and <paramref name="key"/> does not implement the <b>IComparable</b> interface.</para>
  /// </exception>
  /// <exception cref="InvalidOperationException">The comparer throws an exception.</exception>
  /// <exception cref="NotSupportedException">
  ///  <para>The <see cref="<%= ClassName %>"/> is read-only.</para>
  ///  <para>-or-</para>
  ///  <para>The <b><%= ClassName %></b> has a fixed size.</para>
  /// </exception>
  <% } %>
  public virtual void Add(<%= KeyType %> key, <%= ItemType %> value)
  {
   if (Object.ReferenceEquals(key, null)) // avoids compiler error for null check on value type
    throw new ArgumentNullException("key", "The key cannot be null.");

   int index = Array.BinarySearch(keys, 0, count, key, comparer);

   if (index >= 0)
    throw new ArgumentException(String.Format("Item has already been added.  Key being added: /"{0}/".", key));
 
   Insert(~index, key, value);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Removes all elements from the <b><%= ClassName %></b>.
  /// </summary>
  /// <exception cref="NotSupportedException">
  ///  <para>The <see cref="<%= ClassName %>"/> is read-only.</para>
  ///  <para>-or-</para>
  ///  <para>The <b><%= ClassName %></b> has a fixed size.</para>
  /// </exception>
  <% } %>
  public virtual void Clear()
  {
   keys = new <%= KeyType %>[DEFAULT_CAPACITY];
   values = new <%= ItemType %>[DEFAULT_CAPACITY];
   count = 0;
   version++;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Creates a shallow copy of the <b><%= ClassName %></b>.
  /// </summary>
  /// <returns>A shallow copy of the <see cref="<%= ClassName %>"/>.</returns>
  <% } %>
  public virtual object Clone()
  {
   <%= ClassName %> newList = new <%= ClassName %>(count);
   Array.Copy(keys, 0, newList.keys, 0, count);
   Array.Copy(values, 0, newList.values, 0, count);
   newList.count = count;
   newList.version = version;
   newList.comparer = comparer;

   return newList;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Determines whether the <b><%= ClassName %></b> contains a specific key.
  /// </summary>
  /// <param name="key">The key to locate in the <see cref="<%= ClassName %>"/>.</param>
  /// <exception cref="ArgumentNullException">The <paramref name="key"/> is a null reference.</exception>
  /// <exception cref="ArgumentException">
  ///  The <paramref name="key"/> is not of a type supported by the <see cref="<%= ClassName %>"/>.
  /// </exception>
  /// <exception cref="InvalidOperationException">The comparer throws an exception.</exception>
  /// <returns>
  ///  <b>true</b> if the <see cref="<%= ClassName %>"/> contains an element with the specified key;
  ///  otherwise, <b>false</b>.
  /// </returns>
  <% } %>
  bool IDictionary.Contains(object key)
  {
   if (key == null)
    throw new ArgumentNullException("key", "The key cannot be null.");

   if (!(key is <%= KeyType %>))
    throw new ArgumentException("The key must be of type: " + typeof(<%= KeyType %>).FullName, "key");

   return (IndexOfKey((<%= KeyType %>)key) >= 0);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Determines whether the <b><%= ClassName %></b> contains a specific key.
  /// </summary>
  /// <param name="key">The key to locate in the <see cref="<%= ClassName %>"/>.</param>
  /// <exception cref="ArgumentNullException">The <paramref name="key"/> is a null reference.</exception>
  /// <exception cref="InvalidOperationException">The comparer throws an exception.</exception>
  /// <returns>
  ///  <b>true</b> if the <see cref="<%= ClassName %>"/> contains an element with the specified
  ///  <paramref name="key"/>; otherwise, <b>false</b>.
  /// </returns>
  <% } %>
  public virtual bool Contains(<%= KeyType %> key)
  {
   return (IndexOfKey(key) >= 0);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Determines whether the <b><%= ClassName %></b> contains a specific key.
  /// </summary>
  /// <param name="key">The key to locate in the <see cref="<%= ClassName %>"/>.</param>
  /// <exception cref="ArgumentNullException">The <paramref name="key"/> is a null reference.</exception>
  /// <exception cref="InvalidOperationException">The comparer throws an exception.</exception>
  /// <returns>
  ///  <b>true</b> if the <see cref="<%= ClassName %>"/> contains an element with the specified
  ///  <paramref name="key"/>; otherwise, <b>false</b>.
  /// </returns>
  <% } %>
  public virtual bool ContainsKey(<%= KeyType %> key)
  {
   return (IndexOfKey(key) >= 0);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Determines whether the <b><%= ClassName %></b> contains a specific value.
  /// </summary>
  /// <param name="value">The value to locate in the <see cref="<%= ClassName %>"/>.</param>
  /// <returns>
  ///  <b>true</b> if the <see cref="<%= ClassName %>"/> contains an element with the specified
  ///  <paramref name="value"/>; otherwise, <b>false</b>.
  /// </returns>
  <% } %>
  public virtual bool ContainsValue(<%= ItemType %> value)
  {
   return (IndexOfValue(value) >= 0);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Copies the <see cref="<%= ClassName %>"/> elements to a one-dimensional <see cref="System.Array"/>
  ///  instance at the specified index.
  /// </summary>
  /// <param name="array">
  ///  The one-dimensional <see cref="System.Array"/> that is the destination of the
  ///  <see cref="DictionaryEntry"/> objects copied from <see cref="<%= ClassName %>"/>.
  ///  The array must have zero-based indexing.
  /// </param>
  /// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
  /// <exception cref="ArgumentNullException"><paramref name="array"/> is a null reference.</exception>
  /// <exception cref="ArgumentOutOfRangeException"><paramref name="arrayIndex"/> is less than zero.</exception>
  /// <exception cref="ArgumentException">
  ///  <para><paramref name="array"/> is multidimensional.</para>
  ///  <para>-or-</para>
  ///  <para><paramref name="arrayIndex"/> is equal to or greater than the length of <paramref name="array"/>.</para>
  ///  <para>-or-</para>
  ///  <para>The number of elements in the source <see cref="<%= ClassName %>"/> is greater than the
  ///  available space from <paramref name="arrayIndex"/> to the end of the destination <paramref name="array"/>.</para>
  /// </exception>
  /// <exception cref="InvalidCastException">
  ///  The type of the source <see cref="<%= ClassName %>"/> cannot be cast automatically to the type
  ///  of the destination <paramref name="array"/>.
  /// </exception>
  <% } %>
  public virtual void CopyTo(Array array, int arrayIndex)
  {
   if (array == null)
    throw new ArgumentNullException("array", "The destination array cannot be null.");
   if (arrayIndex < 0)
    throw new ArgumentOutOfRangeException("arrayIndex", "Destination index cannot be less than zero.");
   if (array.Rank != 1)
    throw new ArgumentException("Multidimensional arrays are not supported.", "array");
   if (arrayIndex >= array.Length)
    throw new ArgumentException("Destination index cannot be greater than the size of the destination array.", "arrayIndex");
   if (count > (array.Length - arrayIndex))
    throw new ArgumentException("Not enough available space in the destination array.");

   for (int i=0; i < count; i++)
   {
    DictionaryEntry entry = new DictionaryEntry(keys[i], values[i]);
    array.SetValue(entry, arrayIndex + i);
   }
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets the value at the specified index of the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="index">The zero-based index of the value to get.</param>
  /// <returns>The value at the specified index of the <see cref="<%= ClassName %>"/>.</returns>
  /// <exception cref="ArgumentOutOfRangeException">
  ///  <paramref name="index"/> is outside the range of valid indices for the <see cref="<%= ClassName %>"/>.
  /// </exception>
  <% } %>
  public virtual <%= ItemType %> GetByIndex(int index)
  {
   if (index < 0 || index >= count)
    throw new ArgumentOutOfRangeException("index", index, "The index is outside the range of valid indices.");

   return values[index];
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Returns an <see cref="IEnumerator"/> that can iterate through the <b><%= ClassName %></b>.
  /// </summary>
  <% } %>
  IEnumerator IEnumerable.GetEnumerator()
  {
   return new SortedListEnumerator(this, 0, count, SortedListEnumerator.DictEntry);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Returns an <see cref="IDictionaryEnumerator"/> that can iterate through the
  ///  <b><%= ClassName %></b>.  
  /// </summary>
  /// <returns>An <see cref="IDictionaryEnumerator"/> for the <see cref="<%= ClassName %>"/>.</returns>
  <% } %>
  public virtual IDictionaryEnumerator GetEnumerator()
  {
   return new SortedListEnumerator(this, 0, count, SortedListEnumerator.DictEntry);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets the key at the specified index of the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="index">The zero-based index of the key to get.</param>
  /// <returns>The key at the specified index of the <see cref="<%= ClassName %>"/>.</returns>
  /// <exception cref="ArgumentOutOfRangeException">
  ///  <paramref name="index"/> is outside the range of valid indices for the <see cref="<%= ClassName %>"/>.
  /// </exception>
  <% } %>
  public virtual <%= KeyType %> GetKey(int index)
  {
   if (index < 0 || index >= count)
    throw new ArgumentOutOfRangeException("index", index, "The index is outside the range of valid indices.");

   return keys[index];
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets the keys in the <b><%= ClassName %></b>.
  /// </summary>
  /// <returns>An <see cref="IList"/> containing the keys in the <see cref="<%= ClassName %>"/>.</returns>
  /// <remarks>
  ///  <para>The returned <see cref="IList"/> is a read-only view of the keys in the
  ///  <see cref="<%= ClassName %>"/>. Modifications made to the underlying <b><%= ClassName %></b>
  ///  are immediately reflected in the <b>IList</b>.</para>
  ///  <para>The elements of the <b>IList</b> are sorted in the same order as the keys
  ///  of the <b><%= ClassName %></b>.</para>
  ///  <para>Similar to <see cref="<%= ClassName %>.Keys"/>, but returns an <b>IList</b>
  ///  instead of an <see cref="ICollection"/>.</para>
  /// </remarks>
  <% } %>
  public virtual IList GetKeyList()
  {
   if (keyList == null)
    keyList = new KeyList(this);

   return keyList;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Gets the values in the <b><%= ClassName %></b>.
  /// </summary>
  /// <returns>An <see cref="IList"/> containing the values in the <see cref="<%= ClassName %>"/>.</returns>
  /// <remarks>
  ///  <para>The returned <see cref="IList"/> is a read-only view of the values in the
  ///  <see cref="<%= ClassName %>"/>. Modifications made to the underlying <b><%= ClassName %></b>
  ///  are immediately reflected in the <b>IList</b>.</para>
  ///  <para>The elements of the <b>IList</b> are sorted in the same order as the values
  ///  of the <b><%= ClassName %></b>.</para>
  ///  <para>Similar to <see cref="<%= ClassName %>.Values"/>, but returns an <b>IList</b>
  ///  instead of an <see cref="ICollection"/>.</para>
  /// </remarks>
  <% } %>
  public virtual IList GetValueList()
  {
   if (valueList == null)
    valueList = new ValueList(this);

   return valueList;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Returns the zero-based index of the specified key in the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="key">The key to locate in the <see cref="<%= ClassName %>"/>.</param>
  /// <returns>
  ///  The zero-based index of <paramref name="key"/>, if <paramref name="key"/> is found in
  ///  the <see cref="<%= ClassName %>"/>; otherwise, -1.
  /// </returns>
  /// <exception cref="ArgumentNullException"><paramref name="key"/> is a null reference.</exception>
  /// <exception cref="InvalidOperationException">The comparer throws an exception.</exception>
  /// <remarks>
  ///  <para>The elements of a <see cref="<%= ClassName %>"/> are sorted by the keys either
  ///  according to a specific <see cref="IComparer"/> implementation specified when the
  ///  <see cref="<%= ClassName %>"/> is created or according to the <see cref="IComparable"/>
  ///  implementation provided by the keys themselves.</para>
  ///  <para>The index sequence is based on the sort sequence. When an element is added,
  ///  it is inserted into <see cref="<%= ClassName %>"/> in the correct sort order, and the
  ///  indexing adjusts accordingly. When an element removed, the indexing also adjusts accordingly.
  ///  Therefore, the index of a specific key-and-value pair might change as elements are added or
  ///  removed from the <see cref="<%= ClassName %>"/>.</para>
  ///  <para>This method uses a binary search algorithm; therefore, the average execution time is
  ///  proportional to Log2(<i>n</i>), where <i>n</i> is <see cref="<%= ClassName %>.Count"/>.</para>
  /// </remarks>
  <% } %>
  public virtual int IndexOfKey(<%= KeyType %> key)
  {
   if (Object.ReferenceEquals(key, null)) // avoids compiler error for null check on value type
    throw new ArgumentNullException("key", "The key cannot be null.");

   int index = Array.BinarySearch(keys, 0, count, key, comparer);

   return (index >= 0 ? index : -1);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Returns the zero-based index of the first occurrence of the specified value in
  ///  the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="value">The value to locate in the <see cref="<%= ClassName %>"/>.</param>
  /// <returns>
  ///  The zero-based index of <paramref name="value"/>, if <paramref name="value"/> is found in
  ///  the <see cref="<%= ClassName %>"/>; otherwise, -1.
  /// </returns>
  /// <remarks>
  ///  <para>The index sequence is based on the sort sequence. When an element is added,
  ///  it is inserted into <see cref="<%= ClassName %>"/> in the correct sort order, and
  ///  the indexing adjusts accordingly. When an element removed, the indexing also adjusts
  ///  accordingly. Therefore, the index of a specific key-and-value pair might change as
  ///  elements are added or removed from the <see cref="<%= ClassName %>"/>.</para>
  ///  <para>The values of the elements of the <see cref="<%= ClassName %>"/> are compared to the
  ///  specified value using the Equals method.</para>
  ///  <para>This method uses a linear search; therefore, the average execution time is
  ///  proportional to <see cref="<%= ClassName %>.Count"/>.</para>
  /// </remarks>
  <% } %>
  public virtual int IndexOfValue(<%= ItemType %> value)
  {
   return Array.IndexOf(values, value, 0, count);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Removes the element with the specified key from the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="key">The key of the element to remove.</param>
  /// <exception cref="ArgumentException">
  ///  The <paramref name="key"/> is not of a type supported by the <see cref="<%= ClassName %>"/>.
  /// </exception>
  /// <exception cref="ArgumentNullException"><paramref name="key"/> is a null reference.</exception>
  /// <exception cref="NotSupportedException">
  ///  <para>The <see cref="<%= ClassName %>"/> is read-only.</para>
  ///  <para>-or-</para>
  ///  <para>The <b><%= ClassName %></b> has a fixed size.</para>
  /// </exception>
  <% } %>
  void IDictionary.Remove(object key)
  {
   if (key == null)
    throw new ArgumentNullException("key", "The key cannot be null.");

   if (!(key is <%= KeyType %>))
    throw new ArgumentException("The key must be of type: " + typeof(<%= KeyType %>).FullName, "key");

   Remove((<%= KeyType %>)key);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Removes the element with the specified key from the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="key">The key of the element to remove.</param>
  /// <exception cref="ArgumentNullException"><paramref name="key"/> is a null reference.</exception>
  /// <exception cref="NotSupportedException">
  ///  <para>The <see cref="<%= ClassName %>"/> is read-only.</para>
  ///  <para>-or-</para>
  ///  <para>The <b><%= ClassName %></b> has a fixed size.</para>
  /// </exception>
  /// <remarks>
  ///  If the <see cref="<%= ClassName %>"/> does not contain an element with the specified key,
  ///  the <b><%= ClassName %></b> remains unchanged. No exception is thrown.
  /// </remarks>
  <% } %>
  public virtual void Remove(<%= KeyType %> key)
  {
   if (Object.ReferenceEquals(key, null)) // avoids compiler error for null check on value type
    throw new ArgumentNullException("key", "The key cannot be null.");

   int index = IndexOfKey(key);
   if (index >= 0)
    RemoveAt(index);
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Removes the element at the specified index of the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="index">The zero-based index of the element to remove.</param>
  /// <exception cref="ArgumentOutOfRangeException">
  ///  <paramref name="index"/> is outside the range of valid indices for the <see cref="<%= ClassName %>"/>.
  /// </exception>
  /// <exception cref="NotSupportedException">
  ///  <para>The <see cref="<%= ClassName %>"/> is read-only.</para>
  ///  <para>-or-</para>
  ///  <para>The <b><%= ClassName %></b> has a fixed size.</para>
  /// </exception>
  /// <remarks>
  ///  <para>The index sequence is based on the sort sequence. When an element is added,
  ///  it is inserted into <see cref="<%= ClassName %>"/> in the correct sort order, and
  ///  the indexing adjusts accordingly. When an element removed, the indexing also adjusts
  ///  accordingly. Therefore, the index of a specific key-and-value pair might change as
  ///  elements are added or removed from the <see cref="<%= ClassName %>"/>.</para>
  ///  <para>In collections of contiguous elements, such as lists, the elements that
  ///  follow the removed element move up to occupy the vacated spot. If the collection is
  ///  indexed, the indices of the elements that are moved are also updated.</para>
  /// </remarks>
  <% } %>
  public virtual void RemoveAt(int index)
  {
   if (index < 0 || index >= count)
    throw new ArgumentOutOfRangeException("index", index, "The index is outside the range of valid indices.");

   count--;
   if (index < count)
   {
    Array.Copy(keys, index + 1, keys, index, count - index);
    Array.Copy(values, index + 1, values, index, count - index);
   }

   // We can't set the deleted entries equal to null, because they might be value types.
   // Instead, we'll create empty single-element arrays of the right type and copy them
   // over the entries we want to erase.
   <%= KeyType %>[] tempKey = new <%= KeyType %>[1];
   <%= ItemType %>[] tempVal = new <%= ItemType %>[1];
   Array.Copy(tempKey, 0, keys, count, 1);
   Array.Copy(tempVal, 0, values, count, 1);

   version++;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Replaces the value at a specific index in the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="index">The zero-based index at which to save <paramref name="value"/>.</param>
  /// <param name="value">The <see cref="<%= ItemType %>"/> to save into the <see cref="<%= ClassName %>"/>.</param>
  /// <exception cref="ArgumentOutOfRangeException">
  ///  <paramref name="index"/> is outside the range of valid indices for the <see cref="<%= ClassName %>"/>.
  /// </exception>
  /// <remarks>
  ///  <para>The index sequence is based on the sort sequence. When an element is added,
  ///  it is inserted into <see cref="<%= ClassName %>"/> in the correct sort order, and
  ///  the indexing adjusts accordingly. When an element removed, the indexing also adjusts
  ///  accordingly. Therefore, the index of a specific key-and-value pair might change as
  ///  elements are added or removed from the <see cref="<%= ClassName %>"/>.</para>
  /// </remarks>
  <% } %>
  public virtual void SetByIndex(int index, <%= ItemType %> value)
  {
   if (index < 0 || index >= count)
    throw new ArgumentOutOfRangeException("index", index, "The index is outside the range of valid indices.");

   values[index] = value;
   version++;
  }

  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Returns a synchronized (thread-safe) wrapper for the <b><%= ClassName %></b>.
  /// </summary>
  /// <param name="list">The <see cref="<%= ClassName %>"/> to synchronize.</param>
  /// <returns>A synchronized (thread-safe) wrapper for the <see cref="<%= ClassName %>"/>.</returns>
  /// <exception cref="ArgumentNullException"><paramref name="list"/> is a null reference.</exception>
  <% } %>
  public static <%= ClassName %> Synchronized(<%= ClassName %> list)
  {
   if (list == null)
    throw new ArgumentNullException("list", "The list cannot be null.");

   return new SyncSortedList(list);
  }
  
  <% if (GenerateDocumentation) { %>
  /// <summary>
  ///  Sets the capacity to the actual number of elements in the <b><%= ClassName %></b>.
  /// </summary>
  /// <exception cref="NotSupportedException">
  ///  <para>The <see cref="<%= ClassName %>"/> is read-only.</para>
  ///  <para>-or-</para>
  ///  <para>The <b><%= ClassName %></b> has a fixed size.</para>
  /// </exception>
  <% } %>
  public virtual void TrimToSize()
  {
   this.Capacity = count;
  }
  #endregion

  #region Private Methods
  private void Insert(int index, <%= KeyType %> key, <%= ItemType %> value)
  {
   if (count == keys.Length)
    EnsureCapacity(count + 1);

   if (index < count)
   {
    Array.Copy(keys, index, keys, index + 1, count - index);
    Array.Copy(values, index, values, index + 1, count - index);
   }

   keys[index] = key;
   values[index] = value;
   count++;
   version++;
  }

  private void EnsureCapacity(int min)
  {
   int newCapacity = ((keys.Length == 0) ? DEFAULT_CAPACITY : keys.Length * 2);
   if (newCapacity < min)
    newCapacity = min;

   this.Capacity = newCapacity;
  }
  #endregion

  #region Nested Class: SyncSortedList
  [Serializable]
  private class SyncSortedList : <%= ClassName %>, IDictionary
  {
   private <%= ClassName %> list;
   private object root;

   internal SyncSortedList(<%= ClassName %> list)
   {
    this.list = list;
    this.root = list.SyncRoot;
   }

   public override int Capacity
   {
    get
    {
     lock (root)
      return list.Capacity;
    }
   }

   public override int Count
   {
    get
    {
     lock (root)
      return list.Count;
    }
   }

   public override bool IsFixedSize
   {
    get
    {
     return list.IsFixedSize;
    }
   }

   public override bool IsReadOnly
   {
    get
    {
     return list.IsReadOnly;
    }
   }

   public override bool IsSynchronized
   {
    get
    {
     return true;
    }
   }

   public override object SyncRoot
   {
    get
    {
     return root;
    }
   }

   object IDictionary.this[object key]
   {
    get
    {
     lock (root)
      return ((IDictionary)list)[key];
    }
    set
    {
     lock (root)
      ((IDictionary)list)[key] = value;
    }
   }

   public override <%= ItemType %> this[<%= KeyType %> key]
   {
    get
    {
     lock (root)
      return list[key];
    }
    set
    {
     lock (root)
      list[key] = value;
    }
   }

   void IDictionary.Add(object key, object value)
   {
    lock (root)
     ((IDictionary)list).Add(key, value);
   }

   public override void Add(<%= KeyType %> key, <%= ItemType %> value)
   {
    lock (root)
     list.Add(key, value);
   }

   public override void Clear()
   {
    lock (root)
     list.Clear();
   }

   public override object Clone()
   {
    lock (root)
     return list.Clone();
   }

   bool IDictionary.Contains(object key)
   {
    lock (root)
     return ((IDictionary)list).Contains(key);
   }

   public override bool Contains(<%= KeyType %> key)
   {
    lock (root)
     return list.Contains(key);
   }

   public override bool ContainsKey(<%= KeyType %> key)
   {
    lock (root)
     return list.ContainsKey(key);
   }

   public override bool ContainsValue(<%= ItemType %> value)
   {
    lock (root)
     return list.ContainsValue(value);
   }

   public override void CopyTo(Array array, int index)
   {
    lock (root)
     list.CopyTo(array, index);
   }

   public override <%= ItemType %> GetByIndex(int index)
   {
    lock (root)
     return list.GetByIndex(index);
   }

   public override IDictionaryEnumerator GetEnumerator()
   {
    lock (root)
     return list.GetEnumerator();
   }

   public override <%= KeyType %> GetKey(int index)
   {
    lock (root)
     return list.GetKey(index);
   }

   public override IList GetKeyList()
   {
    lock (root)
     return list.GetKeyList();
   }

   public override IList GetValueList()
   {
    lock (root)
     return list.GetValueList();
   }

   public override int IndexOfKey(<%= KeyType %> key)
   {
    lock (root)
     return list.IndexOfKey(key);
   }

   public override int IndexOfValue(<%= ItemType %> value)
   {
    lock (root)
     return list.IndexOfValue(value);
   }

   void IDictionary.Remove(object key)
   {
    lock (root)
     ((IDictionary)list).Remove(key);
   }

   public override void Remove(<%= KeyType %> key)
   {
    lock (root)
     list.Remove(key);
   }

   public override void RemoveAt(int index)
   {
    lock (root)
     list.RemoveAt(index);
   }

   public override void SetByIndex(int index, <%= ItemType %> value)
   {
    lock (root)
     list.SetByIndex(index, value);
   }

   public override void TrimToSize()
   {
    lock (root)
     list.TrimToSize();
   }
  }
  #endregion

  #region Nested Class: SortedListEnumerator
  [Serializable]
  private class SortedListEnumerator : IDictionaryEnumerator, ICloneable
  {
   private <%= ClassName %> list;
   private <%= KeyType %> key;
   private <%= ItemType %> value;
   private int index;
   private int startIndex;
   private int endIndex;
   private int version;
   private bool currentValid;
   private int returnType;

   internal const int Keys = 1;
   internal const int Values = 2;
   internal const int DictEntry = 3;

   internal SortedListEnumerator(<%= ClassName %> list, int index, int count, int returnType)
   {
    this.list = list;
    this.index = index;
    this.startIndex = index;
    this.endIndex = index + count;
    this.version = list.version;
    this.returnType = returnType;
    this.currentValid = false;
   }

   public object Clone()
   {
    return this.MemberwiseClone();
   }

   object IDictionaryEnumerator.Key
   {
    get
    {
     CheckState();
     return key;
    }
   }

   public virtual <%= KeyType %> Key
   {
    get
    {
     CheckState();
     return key;
    }
   }

   public virtual DictionaryEntry Entry
   {
    get
    {
     CheckState();
     return new DictionaryEntry(key, value);
    }
   }

   public virtual object Current
   {
    get
    {
     CheckState();

     switch (returnType)
     {
      case Keys:
       return key;
      case Values:
       return value;
      case DictEntry:
      default:
       return new DictionaryEntry(key, value);
     }
    }
   }

   object IDictionaryEnumerator.Value
   {
    get
    {
     CheckState();
     return value;
    }
   }

   public virtual <%= ItemType %> Value
   {
    get
    {
     CheckState();
     return value;
    }
   }

   public virtual bool MoveNext()
   {
    if (version != list.version)
     throw new InvalidOperationException("The collection was modified - enumeration cannot continue.");
    
    if (index < endIndex)
    {
     key = list.keys[index];
     value = list.values[index];
     index++;
     currentValid = true;
     return true;
    }

    // We can't set the entries equal to null, because they might be value types.
    // Instead, we'll create empty single-element arrays of the right type and copy them
    // over the entries we want to erase.
    <%= KeyType %>[] tempKey = new <%= KeyType %>[1];
    <%= ItemType %>[] tempVal = new <%= ItemType %>[1];
    key = tempKey[0];
    value = tempVal[0];
    currentValid = false;
    return false;
   }

   public virtual void Reset()
   {
    if (version != list.version)
     throw new InvalidOperationException("The collection was modified - enumeration cannot continue.");

    // We can't set the entries equal to null, because they might be value types.
    // Instead, we'll create empty single-element arrays of the right type and copy them
    // over the entries we want to erase.
    <%= KeyType %>[] tempKey = new <%= KeyType %>[1];
    <%= ItemType %>[] tempVal = new <%= ItemType %>[1];
    key = tempKey[0];
    value = tempVal[0];
    currentValid = false;
    index = startIndex;
   }

   private void CheckState()
   {
    if (version != list.version)
     throw new InvalidOperationException("The collection was modified - enumeration cannot continue.");
    if (!currentValid)
     throw new InvalidOperationException("Enumeration either has not started or has already finished.");
   }
  }
  #endregion

  #region Nested Class: KeyList
  [Serializable]
  private class KeyList : IList
  {
   private <%= ClassName %> list;

   internal KeyList(<%= ClassName %> list)
   {
    this.list = list;
   }

   public virtual int Count
   {
    get
    {
     return list.Count;
    }
   }

   public virtual bool IsReadOnly
   {
    get { return true; }
   }

   public virtual bool IsFixedSize
   {
    get { return true; }
   }

   public virtual bool IsSynchronized
   {
    get { return list.IsSynchronized; }
   }

   public virtual object SyncRoot
   {
    get { return list.SyncRoot; }
   }

   public virtual int Add(object key)
   {
    throw new NotSupportedException("Cannot add to a read-only list.");
   }

   public virtual void Clear()
   {
    throw new NotSupportedException("Cannot clear a read-only list.");
   }

   bool IList.Contains(object key)
   {
    return ((IDictionary)list).Contains(key);
   }

   public virtual bool Contains(<%= KeyType %> key)
   {
    return list.Contains(key);
   }

   public virtual void CopyTo(Array array, int index)
   {
    if (array != null && array.Rank != 1)
     throw new ArgumentException("Multidimensional arrays are not supported.", "array");

    Array.Copy(list.keys, 0, array, index, list.Count);
   }

   public virtual void Insert(int index, object value)
   {
    throw new NotSupportedException("Cannot insert into a read-only list.");
   }

   object IList.this[int index]
   {
    get
    {
     return list.GetKey(index);
    }
    set
    {
     throw new NotSupportedException("Cannot modify a read-only list.");
    }
   }

   public virtual <%= KeyType %> this[int index]
   {
    get
    {
     return list.GetKey(index);
    }
    set
    {
     throw new NotSupportedException("Cannot modify a read-only list.");
    }
   }

   public virtual IEnumerator GetEnumerator()
   {
    return new SortedListEnumerator(list, 0, list.Count, SortedListEnumerator.Keys);
   }

   int IList.IndexOf(object key)
   {
    if (!(key is <%= KeyType %>))
     throw new ArgumentException("The key must be of type: " + typeof(<%= KeyType %>).FullName, "key");

    return list.IndexOfKey((<%= KeyType %>)key);
   }

   public virtual int IndexOf(<%= KeyType %> key)
   {
    return list.IndexOfKey(key);
   }

   public virtual void Remove(object key)
   {
    throw new NotSupportedException("Cannot modify a read-only list.");
   }

   public virtual void RemoveAt(int index)
   {
    throw new NotSupportedException("Cannot modify a read-only list.");
   }
  }
  #endregion

  #region Nested Class: ValueList
  [Serializable]
  private class ValueList : IList
  {
   private <%= ClassName %> list;

   internal ValueList(<%= ClassName %> list)
   {
    this.list = list;
   }

   public virtual int Count
   {
    get
    {
     return list.Count;
    }
   }

   public virtual bool IsReadOnly
   {
    get { return true; }
   }

   public virtual bool IsFixedSize
   {
    get { return true; }
   }

   public virtual bool IsSynchronized
   {
    get { return list.IsSynchronized; }
   }

   public virtual object SyncRoot
   {
    get { return list.SyncRoot; }
   }

   public virtual int Add(object key)
   {
    throw new NotSupportedException("Cannot add to a read-only list.");
   }

   public virtual void Clear()
   {
    throw new NotSupportedException("Cannot clear a read-only list.");
   }

   bool IList.Contains(object value)
   {
    if (!(value is <%= ItemType %>))
     throw new ArgumentException("The value must be of type: " + typeof(<%= ItemType %>).FullName, "value");

    return list.ContainsValue((<%= ItemType %>)value);
   }

   public virtual bool Contains(<%= ItemType %> value)
   {
    return list.ContainsValue(value);
   }

   public virtual void CopyTo(Array array, int index)
   {
    if (array != null && array.Rank != 1)
     throw new ArgumentException("Multidimensional arrays are not supported.", "array");

    Array.Copy(list.values, 0, array, index, list.Count);
   }

   public virtual void Insert(int index, object value)
   {
    throw new NotSupportedException("Cannot insert into a read-only list.");
   }

   object IList.this[int index]
   {
    get
    {
     return list.GetByIndex(index);
    }
    set
    {
     if (!(value is <%= ItemType %>))
      throw new ArgumentException("The value must be of type: " + typeof(<%= ItemType %>).FullName, "value");

     list.SetByIndex(index, (<%= ItemType %>)value);
    }
   }

   public virtual <%= ItemType %> this[int index]
   {
    get
    {
     return list.GetByIndex(index);
    }
    set
    {
     list.SetByIndex(index, value);
    }
   }

   public virtual IEnumerator GetEnumerator()
   {
    return new SortedListEnumerator(list, 0, list.Count, SortedListEnumerator.Values);
   }

   int IList.IndexOf(object value)
   {
    if (!(value is <%= ItemType %>))
     throw new ArgumentException("The value must be of type: " + typeof(<%= ItemType %>).FullName, "value");

    return list.IndexOfValue((<%= ItemType %>)value);
   }

   public virtual int IndexOf(<%= ItemType %> value)
   {
    return list.IndexOfValue(value);
   }

   public virtual void Remove(object key)
   {
    throw new NotSupportedException("Cannot modify a read-only list.");
   }

   public virtual void RemoveAt(int index)
   {
    throw new NotSupportedException("Cannot modify a read-only list.");
   }
  }
  #endregion
 }
<% if (ClassNamespace != null && ClassNamespace.Length > 0) { %>
}
<% } %>
<script runat="template">
public enum AccessibilityEnum
{
 Public,
 Protected,
 Internal,
 ProtectedInternal,
 Private
}

public string GetAccessModifier(AccessibilityEnum accessibility)
{
 switch (accessibility)
 {
  case AccessibilityEnum.Public: return "public";
  case AccessibilityEnum.Protected: return "protected";
  case AccessibilityEnum.Internal: return "internal";
  case AccessibilityEnum.ProtectedInternal: return "protected internal";
  case AccessibilityEnum.Private: return "private";
  default: return "public";
 }
}
</script>
 

原创粉丝点击