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:
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
- 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.
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