C# для профессионалов. Том II
Шрифт:
int wheels, doors, headlights;
public Car(int wheels, int doors, int headlights) {
this.wheels = wheels;
this.doors = doors;
this.headlights = headlights;
}
public Car AddWheel(Two.Wheels w) {
this.wheels += w.Number;
return this;
}
internal int Wheels {
set {
wheels = value;
}
get {
return wheels;
}
}
/// <summary>
///
выполняет операцию сложения на Wheel и Car
/// </summary>
/// <param name="c1">car</param>
/// <param name="w1">wheel</param>
/// <returns></returns>
public static Car operator +(Car c1, Wheels w1) {
c1.Wheels += w1.Number;
return c1;
}
/// <summary>
/// выполняет операцию вычитания на Wheel и Car
/// </summary>
/// <param name="c1">car</param>
/// <param name="w1">wheel</param>
/// <returns></returns>
public static Car operator -(Car c1, Wheels w1) {
c1.Wheels -= w1.Number;
return c1;
}
public override string ToString {
return
"[wheels = " + wheels + "| doors = " + doors + "|"
+ " headlights = " + headlights + "]";
}
}
В класс
Car
также был добавлен метод AddWheel
. Представленный далее фрагмент кода проверяет функциональность, только что добавленную в Car
: public static void Main(String[] args) {
Wheels front = 2;
Wheels back = 4;
Wheels total = front + back;
Car greenFordExpedition = new Car(0, 4, 2);
Console.WriteLine("initial:\t" + greenFordExpedition);
greenFordExpedition += total;
Console.WriteLine("after add:\t" + greenFordExpedition);
greenFordExpedition -= front;
Console.WriteLine("after subtract:\t" + greenFordExpedition);
}
Компиляция и выполнение этого кода создадут приведенные ниже результаты:
initial: CAR-[wheels = 0| doors = 4| headlights = 2 ]
after add: CAR-[wheels = 6| doors = 4| headlights = 2 ]
after subtract: CAR-[wheels = 4| doors = 4| headlights = 2 ]
sizeof и typeof
Так как Java не имеет других типов данных значений, кроме примитивных, размер которых всегда известен, то реального применения для оператора
sizeof
нет. В C# типы данных значений охватывают примитивные типы, а также структуры и перечисления. Конечно, как и в Java, размер примитивных типов известен. Однако необходимо знать, сколько пространства занимает тип struct
или enum
, для чего служит оператор sizeof
. Синтаксис достаточно простой: sizeof(<Value Type>)
, где <Value Type>
будет struct
или enum
. Необходимо отметить один момент при использовании оператора sizeof
— он может использоваться только в ненадежном контексте. Оператор sizeof
не может быть перезагружен. Оператор
typeof
используется для получения объекта типа экземпляра типа без создания экземпляра типа. В Java каждый тип имеет переменную класса public static
, которая возвращает дескриптор объекта Class
, ассоциированный с этим классом. Оператор typeof
предоставляет функциональность этого типа. Так же как в случае sizeof
, синтаксис будет очень простым: typeof(<Type>)
, где <Type>
является любым типом, определенным пользователем, который вернет объект типа этого типа. Делегаты
Делегаты являются членами пространства имен, которые инкапсулируют ссылку на метод внутри объекта делегата. Объект делегата может затем передаваться в код, вызывающий указанный метод, не зная во время компиляции, какой метод будет вызван. Красоту, мощь и гибкость делегатов можно увидеть только с помощью примера. Давайте посмотрим, как работают делегаты:
namespace Samples {
using System;
using System.Collections;
public delegate void TestDelegate(string k); // определяет делегата,
// который получает строку в качестве аргумента
public class Sample {
public Sample {}
public void test(string i) {
Console.WriteLine(i + " has been invoked.");
}
public void text2(string j) {
Console.WriteLine("this is another way to invoke {0}" + j);
}
public static void Main(string[] args) {
Sample sm = new Sample;
TestDelegate aDelegate = new TestDelegate(sm.test);
TestDelegate anotherDelegate = new TestDelegate(sm.test2);
aDelegate("test");
anotherDelegate("test2");
}
}
}
Первый шаг по использованию делегатов состоит в определении делегата. Наш тестовый делегат определяется в строке
public delegate void TestDelegate(string k);
. Затем определяется класс с методами, которые имеют сигнатуру, аналогичную делегату. Конечный шаг заключается в создании экземпляра делегата который создается так же, как экземпляр класса и реализуется с помощью оператора new
. Единственное различие состоит в том, что имя целевого метода передается делегату как аргумент. Затем вызывается делегат. В примере вызывается экземпляр aDelegate
с помощью вызова aDelegate("test");
.
Поделиться с друзьями: