Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Перегрузка операций сравнения
В 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 с.) |