CollectionBase.cs

/*
    Questo esempio implementa una collezione Orders di elementi di tipo Order.
    La classe Orders è ottenuta derivando da CollectionBase. Alla classe comunque 
    sono stati aggiunti i metodi Strong-Typed oltre a quelli ereditati da CollectionBase
    ed implementati esplicitamente sulle interfaccie IList, ICollection e IEnumerable.
*/

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

//
//-----------------------------------------------------------------------------------------------
// 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 per verificare che l'evento OnValidate intercetta 
    // l'errore solo a Run-Time
    //aList.Add("Alexander");
    return;

  }
}


//
//-----------------------------------------------------------------------------------------------
// 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;}
  }
}
    
//    
//-----------------------------------------------------------------------------------------------
// Collection: Orders
//-----------------------------------------------------------------------------------------------
//
public class Orders : sysCols.CollectionBase {

  //////////////////////////////////////////////////////////////////////////////////
  // FOUNDATION MEMBERS
  //////////////////////////////////////////////////////////////////////////////////

  // Default Constructor
  public Orders() {}        
  // Constructor
  public Orders(Order[] value) {this.AddRange(value);}
  // Copy-Constructor
  public Orders(Orders value) {this.AddRange(value);}
        
  //////////////////////////////////////////////////////////////////////////////////
  // MODIFIERS MEMBERS
  //////////////////////////////////////////////////////////////////////////////////

  public Order this[int index] 
  {
    get {return ((Order)(List[index]));}
    set {List[index] = value;}
  }
  
  // Type-safe version of IList.Add
  public int Add(Order value) {return List.Add(value);}
        
  // Type-safe version of IList.AddRange
  public void AddRange(Order[] value) 
  {
    for (int i = 0; (i < value.Length); i = (i + 1)) 
      this.Add(value[i]);
  }
        
  // Type-safe version of IList.AddRange
  public void AddRange(Orders value) 
  {
    for (int i = 0; (i < value.Count); i = (i + 1)) 
      this.Add(value[i]);
  }
        
  // Type-safe version of IList.Insert
  public void Insert(int index, Order value) {List.Insert(index, value);}
        
  // Type-safe version of IList.Remove
  public void Remove(Order value) {List.Remove(value);}
        
  //////////////////////////////////////////////////////////////////////////////////
  // ACCESSOR MEMBERS
  //////////////////////////////////////////////////////////////////////////////////

  // Type-safe version of IList.Contains
  public bool Contains(Order value) {return List.Contains(value);}
        
  // Type-safe version of ICollection.CopyTo
  public void CopyTo(Order[] array, int index) {List.CopyTo(array, index);}
        
  // Type-safe version of IList.IndexOf
  public int IndexOf(Order value) {return List.IndexOf(value);}
        
  // Type-safe version of IEnumerable.GetEnumerator
  public new OrderEnumerator GetEnumerator() {
    return new OrderEnumerator(this);
  }
                        
  //////////////////////////////////////////////////////////////////////////////////
  // EVENTS & DELEGATES
  //////////////////////////////////////////////////////////////////////////////////

  protected override void OnValidate(object value)
  {
    if(value == null || value is Order )
      return;

    throw new sys.ArgumentException("Sono permessi solo elementi di tipo Order.");
  }

  //////////////////////////////////////////////////////////////////////////////////
  // NESTED ITERATOR
  //////////////////////////////////////////////////////////////////////////////////

  // Type-safe nested iterator class
  public class OrderEnumerator : sysCols.IEnumerator {            
    private sysCols.IEnumerator baseEnumerator;            
            
    public OrderEnumerator(Orders mappings) {
      sysCols.IEnumerable temp = ((sysCols.IEnumerable)(mappings));
      this.baseEnumerator = temp.GetEnumerator();
    }
            
    // Type-safe iterator Current method 
    public Order Current {
      get {return ((Order)(baseEnumerator.Current));}
    }
           
    // Type-unsafe IEnumerator.Current
    object sysCols.IEnumerator.Current {
      get {return baseEnumerator.Current;}
      }
            
    public bool MoveNext() {return baseEnumerator.MoveNext();}            
    bool sysCols.IEnumerator.MoveNext() {return baseEnumerator.MoveNext();}
            
    public void Reset() {baseEnumerator.Reset();}            
    void sysCols.IEnumerator.Reset() {baseEnumerator.Reset();}
  }
}