InnerArray.cs


using sys = System;
using sysCols = System.Collections;

//------------------------------------------------------------------------------
// <autogenerated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if 
//     the code is regenerated.
// </autogenerated>
//------------------------------------------------------------------------------

using System;
using System.Collections;

public interface IOrdersEnumerator
{
  Order Current {get;}
  bool MoveNext();
  void Reset();
}


[Serializable]
public class Orders : ICollection, IList, IEnumerable
{
  private const int DEFAULT_CAPACITY = 16;
  private Order[] m_array;
  private int m_count = 0;
  private int m_version = 0;
    
  public static Orders Synchronized(Orders list)
  {
    if(list==null)
      throw new ArgumentNullException("list");
    return new SyncOrders(list);
  }
        
  public static Orders ReadOnly(Orders list)
  {
    if(list==null)
      throw new ArgumentNullException("list");
    return new ReadOnlyOrders(list);
  }

  public Orders()  {m_array = new Order[DEFAULT_CAPACITY];}
        
  public Orders(int capacity)  {m_array = new Order[capacity];}

  public Orders(Orders c) {
    m_array = new Order[c.Count];
    AddRange(c);
  }

  public Orders(Order[] a)
  {
    m_array = new Order[a.Length];
    AddRange(a);
  }

  public virtual int Count {get { return m_count; }}

  public virtual void CopyTo(Order[] array) {this.CopyTo(array, 0);}

  public virtual void CopyTo(Order[] array, int start)
  {
    if (m_count > array.GetUpperBound(0)+1-start)
      throw new System.ArgumentException("Destination array was not long enough.");
    for (int i=0; i != m_count; ++i)
      array[start+i] = m_array[i];
  }

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

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

  public virtual Order this[int index]
  {
    get
    {
      ValidateIndex(index); // throws
      return m_array[index]; 
    }
    set
    {
      ValidateIndex(index); // throws
      ++m_version; 
      m_array[index] = value; 
    }
  }

  public virtual int Add(Order item)
  {
    ++m_version;
            
    if (NeedsGrowth())
      Grow();

    m_array[m_count] = item;
    return m_count++;
  }
        
  public virtual void Clear()
  {
    ++m_version;
    m_array = new Order[DEFAULT_CAPACITY];
    m_count = 0;
  }

  public virtual bool Contains(Order item)
  {
    for (int i=0; i != m_count; ++i)
      if (m_array[i].Equals(item))
        return true;
    return false;
  }

  public virtual int IndexOf(Order item)
  {
    for (int i=0; i != m_count; ++i)
      if (m_array[i].Equals(item))
        return i;
    return -1;
  }

  public virtual void Insert(int index, Order item)
  {
    ValidateIndex(index, true); // throws
    ++m_version;
            
    if (NeedsGrowth())
      Grow();

    for (int i=m_count; i > index; --i)
      m_array[i] = m_array[i-1];

    m_array[index] = item;
    m_count++;
  }

  public virtual void Remove(Order item)
  {           
    int i = IndexOf(item);
    if (i < 0)
      throw new System.ArgumentException("Cannot remove the specified item because it was not found in the specified Collection.");
            
    ++m_version;
    RemoveAt(i);
  }

  public virtual void RemoveAt(int index)
  {
    ValidateIndex(index); // throws
    ++m_version;
            
    m_count--;
    for (int i=index; i != m_count; ++i)
      m_array[i] = m_array[i+1];

    if (NeedsTrimming())
      Trim();
  }

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

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

  public virtual IOrdersEnumerator GetEnumerator()
  {
    return new Enumerator(this);
  }

  public virtual int Capacity
  {
    get { return m_array.Length; }
            
    set
    {
      ++m_version;

      if (value < m_count)
        value = m_count;

      if (value != Capacity)
      {
        Order[] temp = new Order[value];
        for (int i=0; i != m_count; ++i)
          temp[i] = m_array[i];
        m_array = temp;
      }
    }
  }

  public virtual int AddRange(Orders x)
  {
    ++m_version;
            
    int r = m_count;
    for (int i=0; i != x.Count; ++i)
      Add(x[i]);
    return r;
  }

  public virtual int AddRange(Order[] x)
  {
    ++m_version;
            
    int r = m_count;
    for (int i=0; i != x.Length; ++i)
      Add(x[i]);
    return r;
  }

  private void ValidateIndex(int i)
  {
    ValidateIndex(i,false);
  }

  private void ValidateIndex(int i, bool allowEqualEnd)
  {
    int max = (allowEqualEnd)?(m_count):(m_count-1);
    if (i < 0 || i > max)
      throw new System.ArgumentOutOfRangeException("Index was out of range.  Must be non-negative and less than the size of the collection.", (object)i, "Specified argument was out of the range of valid values.");
  }

  private bool NeedsGrowth() {return (m_count >= Capacity);}

  private void Grow()
  {
    ++m_version;
            
    if (NeedsGrowth())
    {
      Order[] temp = new Order[m_count*2];
      for (int i=0; i != m_count; ++i)
        temp[i] = m_array[i];
      m_array = temp;
    }
  }

  private bool NeedsTrimming()
  {
    return (m_count <= Capacity / 3);
  }

  private void Trim()
  {
    ++m_version;
            
    if (NeedsTrimming())
    {
      Order[] temp = new Order[m_count];
      for (int i=0; i != m_count; ++i)
        temp[i] = m_array[i];
      m_array = temp;
    }
  }

  void ICollection.CopyTo(Array array, int start)
  {
    this.CopyTo((Order[])array, start);
  }

  object IList.this[int i]
  {
    get { return (object)this[i]; }
    set { this[i] = (Order)value; }
  }

  int IList.Add(object x)
  {
    return this.Add((Order)x);
  }

  bool IList.Contains(object x)
  {
    return this.Contains((Order)x);
  }

  int IList.IndexOf(object x)
  {
    return this.IndexOf((Order)x);
  }

  void IList.Insert(int pos, object x)
  {
    this.Insert(pos, (Order)x);
  }

  void IList.Remove(object x)
  {
    this.Remove((Order)x);
  }

  void IList.RemoveAt(int pos)
  {
    this.RemoveAt(pos);
  }

  IEnumerator IEnumerable.GetEnumerator()
  {
    return (IEnumerator)(this.GetEnumerator());
  }

  private class Enumerator : IEnumerator, IOrdersEnumerator
  {
    private Orders m_collection;
    private int m_index;
    private int m_version;
            
    internal Enumerator(Orders tc)
    {
      m_collection = tc;
      m_index = -1;
      m_version = tc.m_version;
    }
            
    public Order Current
    {
      get { return m_collection[m_index]; }
    }

    public bool MoveNext()
    {
      if (m_version != m_collection.m_version)
        throw new System.InvalidOperationException("Collection was modified; enumeration operation may not execute.");

      ++m_index;
      return (m_index < m_collection.Count) ? true : false;
    }

    public void Reset() {m_index = -1;}
            
    object IEnumerator.Current {get { return (object)(this.Current); }}
            
  }

  private class SyncOrders : Orders
  {
    private Orders m_collection;
    private object m_root;

    internal SyncOrders(Orders list)
    {
      m_root = list.SyncRoot;
      m_collection = list;
    }

    public override void CopyTo(Order[] array)
    {
      lock(this.m_root)
        m_collection.CopyTo(array);
    }

    public override void CopyTo(Order[] array, int start)
    {
      lock(this.m_root)
        m_collection.CopyTo(array,start);
    }

    public override int Count
    {
      get
      { 
        lock(this.m_root)
          return m_collection.Count;
      }
    }

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

    public override object SyncRoot
    {
      get { return this.m_root; }
    }

    public override Order this[int i]
    {
      get
      {
        lock(this.m_root)
          return m_collection[i];
      }
      set
      {
        lock(this.m_root)
          m_collection[i] = value; 
      }
    }

    public override int Add(Order x)
    {
      lock(this.m_root)
        return m_collection.Add(x);
    }
            
    public override void Clear()
    {
      lock(this.m_root)
        m_collection.Clear();
    }

    public override bool Contains(Order x)
    {
      lock(this.m_root)
        return m_collection.Contains(x);
    }

    public override int IndexOf(Order x)
    {
      lock(this.m_root)
        return m_collection.IndexOf(x);
    }

    public override void Insert(int pos, Order x)
    {
      lock(this.m_root)
        m_collection.Insert(pos,x);
    }

    public override void Remove(Order x)
    {           
      lock(this.m_root)
        m_collection.Remove(x);
    }

    public override void RemoveAt(int pos)
    {
      lock(this.m_root)
        m_collection.RemoveAt(pos);
    }
            
    public override bool IsFixedSize
    {
      get {return m_collection.IsFixedSize;}
    }

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

    public override IOrdersEnumerator GetEnumerator()
    {
      lock(m_root)
        return m_collection.GetEnumerator();
    }

    public override int Capacity
    {
      get
      {
        lock(this.m_root)
          return m_collection.Capacity;
      }
                
      set
      {
        lock(this.m_root)
          m_collection.Capacity = value;
      }
    }

    public override int AddRange(Orders x)
    {
      lock(this.m_root)
        return m_collection.AddRange(x);
    }

    public override int AddRange(Order[] x)
    {
      lock(this.m_root)
        return m_collection.AddRange(x);
    }
  }

  private class ReadOnlyOrders : Orders
  {
    private Orders m_collection;

    internal ReadOnlyOrders(Orders list) {m_collection = list;}
            
    public override void CopyTo(Order[] array) {m_collection.CopyTo(array);}

    public override void CopyTo(Order[] array, int start) {m_collection.CopyTo(array,start);}
    public override int Count {get {return m_collection.Count;}}

    public override bool IsSynchronized {get { return m_collection.IsSynchronized;}}

    public override object SyncRoot {get { return this.m_collection.SyncRoot;}}

    public override Order this[int i]
    {
      get { return m_collection[i]; }
      set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); }
    }

    public override int Add(Order x)
    {
      throw new NotSupportedException("This is a Read Only Collection and can not be modified");
    }
            
    public override void Clear()
    {
      throw new NotSupportedException("This is a Read Only Collection and can not be modified");
    }

    public override bool Contains(Order x)
    {
      return m_collection.Contains(x);
    }

    public override int IndexOf(Order x)
    {
      return m_collection.IndexOf(x);
    }

    public override void Insert(int pos, Order x)
    {
      throw new NotSupportedException("This is a Read Only Collection and can not be modified");
    }

    public override void Remove(Order x)
    {           
      throw new NotSupportedException("This is a Read Only Collection and can not be modified");
    }

    public override void RemoveAt(int pos)
    {
      throw new NotSupportedException("This is a Read Only Collection and can not be modified");
    }
            
    public override bool IsFixedSize
    {
      get {return true;}
    }

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

    public override IOrdersEnumerator GetEnumerator()
    {
      return m_collection.GetEnumerator();
    }


    // (just to mimic some nice features of ArrayList)
    public override int Capacity
    {
      get { return m_collection.Capacity; }
                
      set { throw new NotSupportedException("This is a Read Only Collection and can not be modified"); }
    }

    public override int AddRange(Orders x)
    {
      throw new NotSupportedException("This is a Read Only Collection and can not be modified");
    }

    public override int AddRange(Order[] x)
    {
      throw new NotSupportedException("This is a Read Only Collection and can not be modified");
    }
  }
}

//
//-----------------------------------------------------------------------------------------------
// Item: Order
//-----------------------------------------------------------------------------------------------
//
public class Order {
  private static int globalNum = 1000;
  private int num = ++globalNum;
  private string customer;

  public string Customer {
    get {return customer;}
    set {customer = value;}
  }

  public int Number {
    get {return num;}
  }
}


//
//-----------------------------------------------------------------------------------------------
// Main App
//-----------------------------------------------------------------------------------------------
//

class MainApp{
  public static void Main(){
    //
    // Esercito i costruttori tipizzati
    //
    Order[] myOrdersArray = new Order[10];
    for(int i = myOrdersArray.GetLowerBound(0); i<=myOrdersArray.GetUpperBound(0); ++i)
      myOrdersArray[i] = new Order();
    Orders myOrders = new Orders(myOrdersArray);
    {
      Orders myTmpOrders = new Orders(myOrders);      
      
      // error CS1502: The best overloaded method match for 'Orders.Orders(Order[])' has some invalid arguments
      // Scommenta la linea di codice per verificare che il costruttore tipizzato funziona
      //Orders myTmpOrders2 = new Orders(new object[10]);      
    }
  
    //
    // Esercito l'enumeratore tipizzato
    //
    foreach(Order ord in myOrders)
      sys.Console.WriteLine("Ordine n {0} presente!", ord.Number);

    // error CS0030: Cannot convert type 'Order' to 'string'
    // Scommenta la linea di codice per verificare che il costruttore tipizzato funziona
    //foreach(string ord in myOrders);

    // Scommenta per verificare che il costruttore non tipizzato funziona sempre
    //foreach(object ord in myOrders) {sys.Console.WriteLine(ord);}


    //
    // Esercito i metodi tipizzati
    //
    myOrders.Add(new Order());

    // error CS1502: The best overloaded method match for 'Orders.Add(Order)' has some invalid arguments
    // Scommenta la linea di codice per verificare che il metodo tipizzato funziona
    //myOrders.Add(new object());

    //
    // Esercito i metodi non tipizzati di IList
    //
    sysCols.IList aList = myOrders;
    aList.Add(new Order());
    // Scommenta la linea di codice e verifica che l'errore viene intercettato solo a Run-Time
    //aList.Add("Alexander");
    return;

  }
}