Создание пользовательского индексатора. Перегрузка

advertisement
В С# предусмотрены средства для создания
пользовательских классов-контейнеров, к
внутренним элементам которых можно
обращаться при помощи того же
оператора индекса, что и к элементам
обычного массива встроенных типов. Метод,
который обеспечивает такую возможность,
получил название индексатора (indexer).
public class CarApp
{
public static void Main()
{
Cars carLot = new Cars();
carLot[0] = new Car("FeeFee“, 200, 0);
carLot[1] = new Car("BClunker“, 90, 0);
carLot[2] = new Car("Zippy“, 30, 0):
for(int i = 0; i < 3: i++)
{
Console.WriteLine("Car number {0}:", i);
Console.WriteLine("Name: {0} ",
carLot[i].PetName);
Console.WriteLine("Max speed: { 0 } " ,
carLot[i].MaxSpeed);
}
}
}
В простейшем виде индексатор
создается при помощи синтаксиса
this[].
public Car this[int pos]
{
get
{
if (pos < 0 || pos > 10)
throw new
IndexOutOfRangeExceptlon("Out of range!");
else
return (carArray[pos]):
}
set { carArray[pos] = value: }
}
}
За исключением применения ключевого
слова t h i s, индексатор ничем не
отличается от обычного объявления
свойства С#. Обратите внимание, что
индексатор
не обеспечивает никаких характерных
для массивов С# возможностей, не
считая
применения оператора индекса.
Например, мы не сможем
воспользоваться имеющимся у каждого
массива свойством Length:
Console. WriteLine("Cars in stock: {0}",
carLot. Length);
Язык С# позволяет создавать
пользовательские классы и структуры,
которые будут реагировать по-своему
(как мы определим) на
встроенные операторы, например на
оператор сложения “+”. Этот прием
называется перегрузкой операторов.
Рассматривать перегрузку операторов
мы будем на примере класса Point.
public class Point
{
private int x, y;
public Point() {}
public Point(int xPos, int yPos)
{
x = xPos;
у = yPos:
}
public override string ToString()
{
return "X pas: " +this.x + "Y pos: " +
this.y:
}
}
public static int Main(string[] args)
{
Point ptOne = new Point(100, 100);
Point ptTwo = new Point(40, 40);
Point bigPoint = ptOne + ptTwo;
Console. WrlteLine( "Here is the big
point: {0}“, bigPoint.ToString());
return 0;
}
Чтобы приведенный выше код
заработал, осталось переопределить
оператор “+”. В С# для этого можно
использовать ключевое слово
operator. Обратите внимание, что его
можно использовать только вместе
с ключевым словом static:
public class Point
{
private int x, y;
public Point(){}:
public Point (int xPos, int yPos)
{ x = xPos; у = yPos; }
// Перегружаем оператор сложения
public static Point operator + (Point p1,
Point p2)
{
Point newPoint = new Point(p1.x + p2.x,
p1. у + p2.y);
return newPoint;
}
В С# часто возникает необходимость
замещать метод
System.Object.Equals(), чтобы можно
было выполнять сравнения
структурных типов.
Помимо замещения методов Equals()
и GetHashCode(), скорее всего,
потребуется заместить также и
операторы равенства (= = и !=).
public static bool operator ==(Point p1,
Point p2)
{
return pl.Equals(p2);
}
public static bool operator !=(Point p1,
Point p2);
{
return !p1.Equals(p2);
}
Обратите внимание, что для перегрузки
операторов равенства
мы просто передаем выполнение всей
необходимой работы
замещенному методу Equals(). Теперь,
если нам потребуется использовать
обновленный класс Point в нашей
программе, мы можем сделать это
следующим образом:
// Применяем перегруженные операторы
равенства
public static int Main(string[] args)
{
If (ptOne = = ptTwo)
Console.WriteLine("Same values! ");
else
Console. WriteLine("Nope. different
values");
If (ptOne != ptTwo)
Console.WriteLine( "These are not
equal");
else
Console.WriteLine("Same values!");
}
Еще один момент, который
необходимо обязательно отметить, —
С# не позволит вам перегрузить
оператор = = без перегрузки
оператора ! = или наоборот.
Как и в случае
с операторами равенства, С# позволяет
производить перегрузку операторов
сравнения только парами. Первая пара —
это операторы < и >, а вторая — <= и >=.
public class Car : IComparable
public int CompareTo(object o)
{
Car temp = (Car)o;
if (this.CarID > temp.CarID)
return 1;
if (this.CarID < temp.CarID)
return -1;
else
return 0;
}
public static bool operator < (Car c1, Car c2)
{
IComparable itfComp = (IComparable)c1;
return (itfComp. CompareTo(c2) < 0);
}
public static bool operator > (Car c1, Car c2)
{
(Comparable itfComp = (IComparable)cl;
return (itfComp. CompareTo(c2) > 0);
}
public static bool operator <= (Car c1, Car c2)
{
IComparable itfCornp = (IComparable)cl;
return (itfComp, CompareTo(c2) <= 0);
}
public static bool operator >= (Car c1. Car c2)
IComparable itfComp = (IComparable)c1;
return (itfComp. CornpareTo(c2) >= 0);
}
Download