Csharp/CSharp Tutorial/Class/Indexer
Содержание
- 1 Creating One-Dimensional Indexers
- 2 Define both int and string indexer for a class
- 3 Define getter only indexer
- 4 Indexer based on 0 or non-zero
- 5 Indexer based on switch statement
- 6 Indexer for generic type
- 7 Indexers don"t have to operate on actual arrays
- 8 Indexing with an Integer Indexer
- 9 Indexing with an String Indexer
- 10 Indexing with Multiple Parameters
- 11 Overload the MyArray indexer
- 12 Use an indexer to create a fail-soft array.
- 13 Use indexer to add element
Creating One-Dimensional Indexers
A one-dimensional indexer has this general form:
<source lang="csharp">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 } }</source>
Define both int and string indexer for a class
<source lang="csharp">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; }
}</source>
C
Define getter only indexer
<source lang="csharp">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]); }
}</source>
myEmployee[0] = T myEmployee[1] = M
Indexer based on 0 or non-zero
<source lang="csharp">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]); }
}</source>
Values -- T0: 0, T1: 0 Values -- T0: 15, T1: 20
Indexer based on switch statement
<source lang="csharp">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]); }
}</source>
0, 1, 2
Indexer for generic type
<source lang="csharp">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(); } }
}</source>
Rectangle.Draw Circle.Draw
Indexers don"t have to operate on actual arrays
<source lang="csharp">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(); }
}</source>
1 2 3 4 5 6 7 8
Indexing with an Integer Indexer
- It is possible to overload the [ ] operator for classes that you create with an indexer.
- An indexer allows an object to be indexed like an array.
<source lang="csharp">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; }
}</source>
Column 0: 5551212
Indexing with an String Indexer
<source lang="csharp">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); }
}</source>
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
<source lang="csharp">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"]); }
}</source>
A4 = A4 H4 = H4
Overload the MyArray indexer
<source lang="csharp">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]); }
}</source>
myArray[1]: 1 myArray[2]: 2 myArray[1.1]: 1 myArray[1.6]: 1
Use an indexer to create a fail-soft array.
<source lang="csharp">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"); } }
}</source>
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
<source lang="csharp">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;
}</source>
Employee number 0: Name: F Employee number 1: Name: C Employee number 2: Name: Z Using IEnumerable Name: F Name: C Name: Z