Csharp/CSharp Tutorial/Class/Indexer

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Creating One-Dimensional Indexers

A one-dimensional indexer has this general form:


element-type this[int index] {
        // The get accessor.
        get {
            // return the value specified by index 
        }
        
        // The set accessor.
        set {
            // set the value specified by index 
        }
    }

Define both int and string indexer for a class

using System;
using System.Collections;
using System.Collections.Specialized;
public class MainClass
{
  public static void Main()
  {
    EmployeeList carLot = new EmployeeList();
    
    carLot["A"] = new Employee("A");
    carLot["B"] = new Employee("B");
    carLot["C"] = new Employee("C");
    Employee zippy = carLot["C"];
    Console.WriteLine(zippy.Name);
  }
}
public class EmployeeList
{
  private ListDictionary carDictionary;
  
  public EmployeeList()
  {
    carDictionary = new ListDictionary();
  }
  // The string indexer.
  public Employee this[string name]
  {
    get { return (Employee)carDictionary[name];}
    set { carDictionary.Add(name, value);}
  }
  
  // The int indexer.
  public Employee this[int item]
  {
    get { return (Employee)carDictionary[item];}
    set { carDictionary.Add(item, value);}
  }
}
public class Employee
{
    public string Name = "";
    
  public Employee(string n)
  {
      Name = n;
  }
}
C

Define getter only indexer

using System;
public class Employee
{
  private string firstName;
  private string lastName;
  public Employee(string firstName, string lastName)
  {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  public string this[int index]
  {
    get
    {
      switch (index)
      {
        case 0:
          return firstName;
        case 1:
          return lastName;
        default:
          throw new IndexOutOfRangeException();
      }
    }
  }
}
class MainClass
{
  public static void Main()
  {
    Employee myEmployee = new Employee("T", "M");
    Console.WriteLine("myEmployee[0] = " + myEmployee[0]);
    Console.WriteLine("myEmployee[1] = " + myEmployee[1]);
  }
}
myEmployee[0] = T
myEmployee[1] = M

Indexer based on 0 or non-zero

using System;
class MyClass
{
   int value0; 
   int value1; 
   public int this[int index] 
   {
      get
      {
         return (0 == index) ? value0 : value1;
      }
      set
      {
         if (0 == index)
            value0 = value; 
         else
            value1 = value; 
      }
   }
}
class MainClass
{
   static void Main()
   {
      MyClass a = new MyClass();
      Console.WriteLine("Values -- T0: {0}, T1: {1}", a[0], a[1]);
      a[0] = 15;
      a[1] = 20;
      Console.WriteLine("Values -- T0: {0}, T1: {1}", a[0], a[1]);
   }
}
Values -- T0: 0, T1: 0
Values -- T0: 15, T1: 20

Indexer based on switch statement

using System;

class MyClass
{
   public string value0;             
   public string value1;            
   public string value2;          
   
   public string this[int index] 
   {
      set 
      {
         switch (index)
         {
            case 0: value0 = value;
               break;
            case 1: value1 = value;
               break;
            case 2: value2 = value;
               break;
         }
      }
      get 
      {
         switch (index)
         {
            case 0: return value0;
            case 1: return value1;
            case 2: return value2;
            default:
               return "";
         }
      }
   }
}
class MainClass
{
   static void Main()
   {
      MyClass myObject = new MyClass();
      myObject.value0 = "0";
      myObject.value1 = "1";
      myObject.value2 = "2";
      Console.WriteLine("{0}, {1}, {2}", myObject[0], myObject[1], myObject[2]);
   }
}
0, 1, 2

Indexer for generic type

using System.Collections;
public abstract class Shape
{
   public abstract void Draw();
}
public class Rectangle : Shape
{
   public override void Draw()
   {
      System.Console.WriteLine( "Rectangle.Draw" );
   }
}
public class Circle : Shape
{
   public override void Draw()
   {
      System.Console.WriteLine( "Circle.Draw" );
   }
}
public class ShapeList
{
   private ArrayList shapes;
   public ShapeList()
   {
      shapes = new ArrayList();
   }
   public int Count
   {
      get
      {
         return shapes.Count;
      }
   }
   public Shape this[ int index ]
   {
      get
      {
         return (Shape) shapes[index];
      }
   }
   public void Add( Shape shape )
   {
      shapes.Add( shape );
   }
}
public class MainClass
{
   static void Main()
   {
      ShapeList drawing = new ShapeList();
      drawing.Add( new Rectangle() );
      drawing.Add( new Circle() );
      
      for( int i = 0; i < drawing.Count; ++i ) {
         Shape shape = drawing[i];
         shape.Draw();
      }
   }
}
Rectangle.Draw
Circle.Draw

Indexers don"t have to operate on actual arrays

using System; 
 
class MySequence {  
 
  public int this[int index] { 
    get { 
      return index + 1; 
    } 
 
  } 
}  
  
class MainClass {  
  public static void Main() {  
    MySequence sequence = new MySequence(); 
 
    for(int i=0; i < 8; i++) 
      Console.Write(sequence[i] + " "); 
    Console.WriteLine(); 
  } 
}
1 2 3 4 5 6 7 8

Indexing with an Integer Indexer

  1. It is possible to overload the [ ] operator for classes that you create with an indexer.
  2. An indexer allows an object to be indexed like an array.


using System;
using System.Collections;
class Pair
{
    public Pair(string name, object data)
    {
        this.name = name;
        this.data = data;
    }
    public string Name
    {
        get
        {
            return(name);
        }
        set
        {
            name = value;
        }
    }
    public object Data
    {
        get
        {
            return(data);
        }
        set
        {
            data = value;
        }
    }
    string    name;
    object data;
}
class PairList
{
    public PairList()
    {
        row = new ArrayList();
    }
    
    public void Load() 
    {
        /* load code here */ 
        row.Add(new Pair("A", 5551212));
        row.Add(new Pair("B", "Fred"));
        row.Add(new Pair("C", 2355.23m));
    }
    
    // the indexer
    public Pair this[int column]
    {
        get
        {
            return((Pair) row[column - 1]);
        }
        set
        {
            row[column - 1] = value;
        }
    }
    ArrayList    row;    
}
class MainClass
{
    public static void Main()
    {
        PairList row = new PairList();
        row.Load();
        Console.WriteLine("Column 0: {0}", row[1].Data);
        row[1].Data = 12;    
    }
}
Column 0: 5551212

Indexing with an String Indexer

using System;
using System.Collections;
class Pair
{
    public Pair(string name, object data)
    {
        this.name = name;
        this.data = data;
    }
    public string Name
    {
        get
        {
            return(name);
        }
        set
        {
            name = value;
        }
    }
    public object Data
    {
        get
        {
            return(data);
        }
        set
        {
            data = value;
        }
    }
    string    name;
    object data;
}
class PairList
{
    public PairList()
    {
        row = new ArrayList();
    }
    
    public void Load() 
    {
        /* load code here */ 
        row.Add(new Pair("Q", 5551212));
        row.Add(new Pair("A", "text"));
        row.Add(new Pair("B", 2355.23m));
    }
    
    public Pair this[int column]
    {
        get
        {
            return( (Pair) row[column - 1]);
        }
        set
        {
            row[column - 1] = value;
        }
    }
    int FindPair(string name)
    {
        for (int index = 0; index < row.Count; index++)
        {
            Pair Pair = (Pair) row[index];
            if (Pair.Name == name)
            return(index);
        }
        return(-1);
    }
    public Pair this[string name]
    {
        get
        {
            return( (Pair) this[FindPair(name)]);
        }
        set
        {
            this[FindPair(name)] = value;
        }
    }
    ArrayList    row;    
}
class Test
{
    public static void Main()
    {
        PairList row = new PairList();
        row.Load();
        Pair val = row["A"];
        Console.WriteLine("A: {0}", val.Data);
        Console.WriteLine("B: {0}", row["B"].Data);
        row["Q"].Data = "new value";    // set the name
        Console.WriteLine("Q: {0}", row["Q"].Data);
    }
}
A: 5551212
B: text
Unhandled Exception: System.ArgumentOutOfRangeException: Index was out of range. Must be non-negativ
e and less than the size of the collection.
Parameter name: index
   at System.Collections.ArrayList.get_Item(Int32 index)
   at PairList.get_Item(Int32 column)
   at Test.Main()

Indexing with Multiple Parameters

using System;
public class Cell
{
    string name;
    
    public Cell(string name)
    {
        this.name = name;
    }
    
    public override string ToString()
    {
        return(name);
    }
}
public class Table
{
    Cell[,] table = new Cell[8, 8];
    
    int RowToIndex(string row)
    {
        string temp = row.ToUpper();
        return((int) temp[0] - (int) "A");
    }
    
    int PositionToColumn(string pos)
    {
        return(pos[1] - "0" - 1);
    }
    
    public Cell this[string row, int column]
    {
        get
        {
            return(table[RowToIndex(row), column - 1]);
        }
        set
        {
            table[RowToIndex(row), column - 1] = value;
        }
    }    
    
    public Cell this[string position]
    {
        get
        {
            return(table[RowToIndex(position),
            PositionToColumn(position)]);
        }
        set
        {
            table[RowToIndex(position),
            PositionToColumn(position)] = value;
        }
    }    
}
class MainClass
{
    public static void Main()
    {
        Table table = new Table();
        
        table["A", 4] = new Cell("A4");
        table["H", 4] = new Cell("H4");
        
        Console.WriteLine("A4 = {0}", table["A", 4]);
        Console.WriteLine("H4 = {0}", table["H4"]);
    }
}
A4 = A4
H4 = H4

Overload the MyArray indexer

using System;  
  
class MyArray {   
  int[] a;    
  
  public int Length;
  
  public bool errflag;
    
  public MyArray(int size) {  
    a = new int[size];  
    Length = size;   
  }  
  
  // This is the int indexer for MyArray.  
  public int this[int index] {  
    get {  
      if(indexCheck(index)) {  
        errflag = false;  
        return a[index];  
      } else {  
        errflag = true;  
        return 0;  
      }  
    }  
  
    set {  
      if(indexCheck(index)) {  
        a[index] = value;  
        errflag = false;  
      }  
      else errflag = true;  
    }  
  }  
  
  public int this[double idx] {  
    get {  
      int index = (int) idx; 
 
      if(indexCheck(index)) {  
        errflag = false;  
        return a[index];  
      } else {  
        errflag = true;  
        return 0;  
      }  
    }  
  
    set {  
      int index = (int) idx; 
 
      if(indexCheck(index)) {  
        a[index] = value;  
        errflag = false;  
      }  
      else errflag = true;  
    }  
  }  
  
  private bool indexCheck(int index) {  
   if(index >= 0 & index < Length) return true;  
   return false;  
  }  
}   
   
class MainClass {   
  public static void Main() {   
    MyArray myArray = new MyArray(5);  
  
    for(int i=0; i < myArray.Length; i++) 
      myArray[i] = i;  
 
    // now index with ints and doubles 
    Console.WriteLine("myArray[1]: " + myArray[1]); 
    Console.WriteLine("myArray[2]: " + myArray[2]); 
 
    Console.WriteLine("myArray[1.1]: " + myArray[1.1]); 
    Console.WriteLine("myArray[1.6]: " + myArray[1.6]); 
 
  }  
}
myArray[1]: 1
myArray[2]: 2
myArray[1.1]: 1
myArray[1.6]: 1

Use an indexer to create a fail-soft array.

using System; 
 
class MyArray {  
  int[] a;
 
  public int Length; 
 
  public bool errflag;
   
  public MyArray(int size) { 
    a = new int[size]; 
    Length = size;  
  } 
 
  // This is the indexer for MyArray. 
  public int this[int index] { 
    get { 
      if(indexCheck(index)) { 
        errflag = false; 
        return a[index]; 
      } else { 
        errflag = true; 
        return 0; 
      } 
    } 
 
    set { 
      if(indexCheck(index)) { 
        a[index] = value; 
        errflag = false; 
      } 
      else errflag = true; 
    } 
  } 
 
  private bool indexCheck(int index) { 
   if(index >= 0 & index < Length) 
      return true; 
   return false; 
  } 
}  
  
class MainClass {  
  public static void Main() {  
    MyArray myArray = new MyArray(5); 
    int x; 
 
    Console.WriteLine("Fail quietly."); 
    for(int i=0; i < 10; i++) 
      myArray[i] = i*10; 
 
    for(int i=0; i < 10; i++) { 
      x = myArray[i]; 
      if(x != -1) Console.Write(x + " "); 
    } 
    Console.WriteLine(); 
 
    Console.WriteLine("\nFail with error reports."); 
    for(int i=0; i < 10; i++) { 
      myArray[i] = i*10; 
      if(myArray.errflag) 
        Console.WriteLine("myArray[" + i + "] out-of-bounds"); 
    } 
 
    for(int i=0; i < 10; i++) { 
      x = myArray[i]; 
      if(!myArray.errflag) 
         Console.Write(x + " "); 
      else 
         Console.WriteLine("myArray[" + i + "] out-of-bounds"); 
    } 
  } 
}
Fail quietly.
0 10 20 30 40 0 0 0 0 0
Fail with error reports.
myArray[5] out-of-bounds
myArray[6] out-of-bounds
myArray[7] out-of-bounds
myArray[8] out-of-bounds
myArray[9] out-of-bounds
0 10 20 30 40 myArray[5] out-of-bounds
myArray[6] out-of-bounds
myArray[7] out-of-bounds
myArray[8] out-of-bounds
myArray[9] out-of-bounds

Use indexer to add element

using System;
using System.Collections;
public class MainClass
{
  public static void Main()
  {
    EmployeeList empList = new EmployeeList();
  
    empList[0] = new Employee("F");
    empList[1] = new Employee("C");
    empList[2] = new Employee("Z");
    for(int i = 0; i < empList.GetNumberOfEmployeeList(); i++)
    {
      Console.WriteLine("Employee number {0}:", i);
      Console.WriteLine("Name: {0}", empList[i].Name);
    }
    try
    {
      Console.WriteLine("Using IEnumerable");
      foreach (Employee c in empList)
      {
        Console.WriteLine("Name: {0}", c.Name);
      }
    }
    catch{}      
  }
}
public class EmployeeList : IEnumerable
{
  private ArrayList carArray;
  public EmployeeList()
  {
    carArray = new ArrayList();
  }
  // The indexer.
  public Employee this[int pos]
  {
    get
    {
      if(pos < 0)
        throw new IndexOutOfRangeException("Hey! Index out of range");
      else
        return (Employee)carArray[pos];
    }
    set
    {
      carArray.Insert(pos, value);
    }
  }
  public int GetNumberOfEmployeeList()
  {
    return carArray.Count;
  }
  public IEnumerator GetEnumerator()
  {
    return carArray.GetEnumerator();
  }
}
public class Employee
{
  public Employee(string name)
  {
    this.Name = name;
  }
  public string Name;
}
Employee number 0:
Name: F
Employee number 1:
Name: C
Employee number 2:
Name: Z
Using IEnumerable
Name: F
Name: C
Name: Z