Перегрузка операций сравнения 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Перегрузка операций сравнения



В C# имеется шесть операций сравнения, которые мы уже представили ранее в этой главе (в разделе “Операции”), и их можно разделить на три пары:

1) == и!=

2) > и <

3) >= и <=

Язык C# требует, чтобы перегрузка этих операций выполнялась попарно. То есть, если вы перегружаете ==, то обязаны также перегрузить!=, иначе получите ошибку компиля­ции. К тому же операции сравнения должны возвращать bool. Это фундаментальное отли­чие операций сравнения от арифметических операций. Так, например, результат сложе­ния или вычитания двух величин теоретически может быть любого типа. И вы уже видели, что умножение двух Vector может быть реализовано так, что возвращается скаляр. Другой пример касается базового класса.NET System.DateTime. Можно вычесть один экземпляр DateTime из другого, но результатом будет не DateTime, a System.TimeSpan. В отличие от этого, для операций сравнения не имеет смысла возвращать что-то, отличное от bool.

Если вы перегружаете == и!=, то должны также переопределить методы Equals() и GetHashCode() из System.Object, иначе получите от компи­лятора предупреждение. Причина в том, что метод Equals() должен реали­зовывать ту же логику сравнения, что и операция ==.

Помимо этого отличия, в остальном перегрузка операций сравнения следует тем же принципам, что и перегрузка арифметических операций. Однако сравнение величин не всегда так просто, как может показаться на первый взгляд. Например, если вы просто срав­ните две объектные ссылки, то при этом просто сравните два адреса памяти, где располо­жены объекты. Это редко бывает тем, что требуется от операции сравнения, а потому вы должны закодировать ее так, чтобы она сравнивала значения объектов и возвращала соот­ветствующее булевское значение. В следующем примере переопределяются операции == и!= для структуры Vector. Ниже показана реализация ==.

public static bool operator== (Vector lhs, Vector rhs)

{

if (lhs.x == rhs.x SS lhs.у == rhs.у && lhs.z == rhs.z)

return true;

else

return false;

}

В этом случае просто сравниваются два объекта Vector на предмет равенства значений соответствующих компонентов. Для большинства структур это именно то, что нужно, хотя иногда приходится тщательно обдумывать, что должно подразумеваться под равенством.

Например, если есть встроенный класс, должны ли вы просто сравнивать ссылки на пред­мет того, указывают они на один и тот же объект (неглубокое сравнение), или же на предмет равенства значений объектов, на которые установлены ссылки (глубокое сравнение)}

Неглубокое сравнение - это когда проверяется, ссылаются ли объекты на одну и ту же область памяти, в то время как глубокое сравнение работает со значениями и свойствами объекта с целью определения эквивалентности. Вы должны выполнять проверку эквивалентности в зависимости от глубины; это поможет решить, что именно вы хотите проверить.

Не поддавайтесь соблазну перегружать операцию сравнения, вызывая метод Equals(), унаследованный от System.Object. Если сделать так, а потом попробовать вычислить (objA== objВ), когда objA содержит null, то исполняющая среда.NET попытается выполнить null.Equals(objB). Обратный вариант (переопределение Equals() для вызова операции сравне­ния) должен быть безопасен.

Также придется перегрузить операцию!=. Ниже показан простейший способ, как это сделать:

public static bool operator!= (Vector lhs, Vector rhs)

{

return!(lhs == rhs);

}

Как обычно, стоит сразу проверить, работает ли полученная перегрузка, написав некоторый тестовый код. На этот раз определим три объекта Vector и сравним их:

static void Main()

{

Vector vect1, vect2, vect3;

Vect1 = new Vector (3.0,3.0,-10.0);

vect2 = new Vector(3.0,3.0,-10.0);

vect3 = new Vector(2.0,3.0,6.0);

Console.WriteLine("vect1==vect2 возвращает " + (vect1==vect2));

Console.WriteLine("vect1==vect3 возвращает " + (vect1==vect3));

Console.WriteLine('vect2==vect3 возвращает " + (vect2==vect3));

Console.WriteLine();

Console.WriteLine("vect1!=vect2 возвращает " + (vect1!=vect2));

Console.WriteLine("vect1!=vect3 возвращает " + (vect1!=vect3));

Console.WriteLine("vect2!=vect3 возвращает " + (vect2!=vect3));

}

При компиляции этого кода генерируется показанное ниже предупреждение компиля­тора, поскольку для структуры Vector не был переопределен метод Equals(). В данном случае это не имеет значения, поэтому его можно проигнорировать,

Сsc Vectors3.cs

Microsoft (R) Visual C# 2010 Compiler version 4.0.21006.1

for Microsoft (R).NET Framework version 4.0

Copyright (C) Microsoft Corporation. All rights reserved.

Vectors3.cs(5,11): warning CS0660: 'Wrox.ProCSharp.OOCSharp.Vector’

defines operator == or operator!= but does not override

Object.Equals(object o)

Vectors3.cs(5,11): warning CS0661: 'Wrox.ProCSharp.OOCSharp.Vector'

defines operator == or operator!= but does not override

Object.GetHashCode()

Vectors3.cs (5,11): Предупреждение CS0660: 'Wrox.ProCSharp.OOCSharp.

Vector' определяет операцию == или!= но не переопределяет

Object.Equals(object о)

Vectors3.cs (5,11): предупреждение CS0661: 'Wrox.ProCSharp.

OOCSharp.Vector ' определяет операцию == или!=, но не переопределяет

Object.GetHashCode()

В результате запуска этого примера на экране появляется следующий вывод:

vect1==vect2 возвращает True

vect1==vect3 возвращает False

vect2==vect3 возвращает False

 

vect1!=vect2 возвращает False

vect1!=vect3 возвращает True

vect2!=vect3 возвращает True

 



Поделиться:


Последнее изменение этой страницы: 2016-12-30; просмотров: 213; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.116.28.22 (0.008 с.)