Книга: C# для профессионалов. Том II
Перезагрузка
Перезагрузка
В начале важно отметить, что перезагрузка операторов не определена в CLS. Однако CLS обращается к ней, потому что языки, обеспечивающие ее функциональность, делают это способом, который могут понять другие языки. Таким образом, языки, которые не поддерживают перезагрузку операторов, все-таки имеют доступ к базовой функциональности. Java является примером языка, который не поддерживает перезагрузку операторов, — ни одна из концепций, рассмотренных в этом разделе, не может ее использовать. Спецификация среды .NET включает ряд рекомендаций для проведения перезагрузки операторов.
? Определите операторы на типах данных значений, которые логически являются встроенным типом языка (таким, как System.Decimal
).
? Используйте методы перезагрузки операторов, включающие только тот класс, на котором определены методы.
? Применяйте соглашения об именах и сигнатурах, описанные в CLS.
? Перезагрузка операторов полезна в случаях, где точно известно, каким будет результат операции.
? Предоставьте альтернативные сигнатуры. Не все языки поддерживают вызов перезагруженных операторов. Поэтому постарайтесь всегда включать вторичный метод с подходящим специфическим для домена именем, который имеет эквивалентную функциональность.
Перезагрузка операторов связана как с определенными пользователем преобразованиями, так и с типом данных, а не с экземпляром. Это означает, что она связана со всем типом данных, а не с каким-то одним экземпляром объекта, то есть операция всегда должна быть static
и public
.
В нижеследующем примере создается тип данных значения Wheels
, который может выполнять перезагруженное сложение с самим собой. Можно отметить частое использование комментариев и тегов типа XML внутри комментариев, они нужны для документации. Документация C# будет обсуждаться ниже в этом приложении:
public struct Wheels {
int wheel;
// загрузить начальное значение в wheel
private Wheels(int initVal); {
wheel = initVal;
}
/// <summary>
/// показывает внутреннее число wheels
/// </summary>
internal int Number {
set {
wheel = value;
}
get {
return wheel;
}
}
/// <summary>
/// возвращает внутреннее число. Если этот метод
/// не переопределен, то возвращаемой строкой будет тип Two.Wheels.
/// </ summary >
/// <returns></returns>
public override string ToString() {
return wheel.ToString();
}
/// < summary>
/// выполнить операцию сложения на двух wheels
/// </summary>
/// <param name="w1"></param>
/// <param name="w2"></param>
/// <returns></returns>
public static Wheels operator + (Wheels w1, Wheels w2) {
w1.wheel += w2.wheel; return w1;
}
/// <summary>
/// предоставляет альтернативную функциональность сложения.
/// отметим, что вторая альтернатива операции сложения
/// находится не в этой структуре, а в классе car
/// </summary>
/// <param name= "w"></param>
/// <returns></returns>
public Wheels AddWeels(Wheels w) {
this.wheel += w.wheel;
return this;
}
/// <summary>
/// поэтому целые литералы можно неявно преобразовать в wheel
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public static implicit operator Wheels(int x) {
return new Wheels(x);
}
}
Здесь выделим использование метода AddWheel()
, что удовлетворяет рекомендациям об альтернативных сигнатурах. Язык CLS, который не поддерживает перезагрузку операторов, может получить доступ к той же функциональности сложения с помощью этого метода. Фрагмент кода ниже показывает, как может использоваться этот тип данных значения:
public static void Main(String[] args) {
Wheels front = 2; // неявное преобразование
Wheels back = 4; // неявное преобразование
Wheels total = front + back; // перезагруженная версия сложения
Console.WriteLine(total);
}
Компиляция и выполнение этого кода дадут в результате 6. Можно также изменить тип Car
, чтобы разрешить сложение и вычитание из него Wheels
. Следующий код показывает изменения, сделанные в классе Car
:
public class Car {
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 ]
- 5.5.2.3. Перезагрузка компьютера
- Выключение, перезагрузка компьютера, завершение сеанса пользователя
- Поисковая оптимизация: перезагрузка. «Соль»
- Глава 1 Перезагрузка репутации в интернете
- Первая перезагрузка
- Перезагрузка КПК
- Перезагрузка операторов
- Перезагрузка продавцов –?методы настройки на эффективность и оптимизм
- Перезагрузка методов
- 5.15. Сбой и перезагрузка на узле сервера
- 6.1. Перезагрузка системы ценностей
- Пример: Employees и Managers