Компиляция и выполнение этого кода создает показанные ниже результаты:
Man -
[arms:5|legs:4|name:john]
Car -
[wheels:4|doors:5|headlights:2]
Перезагрузка
В начале важно отметить, что перезагрузка операторов не определена в 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) {
/// отметим, что вторая альтернатива операции сложения
/// находится не в этой структуре, а в классе 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
. Следующий код показывает изменения, сделанные в классе