Программирование >>  Программирование с использованием ajax 

1 ... 97 98 99 [ 100 ] 101 102 103 ... 396


Такой подход хорош, но существуют и альтернативные варианты. Например, может оказаться предпочтительнее использовать такой синтаксис, как показан ниже:

if (personl > person2)

Подобное делает возможным применение приема перегрузки операций, о котором более подробно будет рассказываться в следующем разделе. Он является мощным, но применять его нужно рассудительно. В приведенном выше коде сразу и не понятно, что сравнивается именно возраст людей, а не рост, вес, коэффициент умственного развития или вообще общая значимость .

Вторым вариантом является применение интерфейсов IComparable и IComparer, которые позволяют определять то, как объекты будут сравниваться друг с другом, стандартным образом. Такой подход поддерживается многими классами коллекций в .NET Framework, что делает его прекрасным способом для сортировки объектов в коллекции.

Перегрузка операций

Перегрузка операций позволяет использовать стандартные операции, вроде +, > и т.д., с классами собственной разработки. Перегрузкой она называется потому, что подразумевает предоставление для этих операций своих собственных реализаций в случае использования параметров специфических типов, во многом подобно перегрузке методов, которая осуществляется путем предоставления разных параметров для методов с одинаковым именем.

Перегрузка операций является полезным приемом, поскольку в реализации перегруженной операции можно выполнять какую угодно обработку, т.е. добиваться выполнения более сложных действий, чем, например, просто сложение двух операндов вместе, если брать операцию +. Чуть позже это будет показано более детально на примере дальнейшей модернизации библиотеки CardLib путем предоставления реализаций для операций сравнений, сравнивающих две карты для выяснения того, какая из них побьет другую в данной партии.

Типы ClassA, ClassB и MyStruct реализуют интерфейс IMylnterface и потому все они являются совместимыми с типом IMylnterface. Тип ClassD унаследован от ClassA и, следовательно, тоже является совместимым с этим типом. Таким образом, получается, что несовместимым с ним является только ClassC.

И, наконец, только переменные самого типа MyStruct и упакованные переменные такого типа являются совместимыми с MyStruct, поскольку преобразовывать ссылочные типы в типы-значения нельзя (хотя упакованные ранее переменные, конечно, можно и распаковать).

Сравнение значений

Возьмем два представляющих людей объекта Person (Человек), каждый из которых имеет целочисленное свойство Age (Возраст). Может возникнуть желание сравнить их для того, чтобы узнать, кто из двух людей является старше. Чтобы сделать это, можно просто использовать и такой код:

if (personl.Age > person2.Age)



Поскольку выигрыш партии во многих карточных играх зависит от масти участвующих карт, простым сравнением чисел на картах здесь не обойтись. Если вторая выкладываемая карта по масти отличается от первой, тогда должна побеждать первая карта, независимо от ее достоинства. Реализовать такое поведение можно, взяв в расчет порядок двух операндов. Еще можно взять в расчет козырную масть, чтобы козырная карта била карты любых других мастей, даже если она не выкладывается первой. Это означает, что выяснение того, что выражение cardl > card2 является истинным (т.е. cardl бьет card2, если cardl выкладывается первой) вовсе не обязательно должно подразумевать, что выражение card2 > cardl является ложным. В случае если ни cardl, ни card2 не являются козырными картами и имеют разную масть, оба этих выражения должны возвращать true.

Сначала, однако, необходимо ознакомиться с базовым синтаксисом перегрузки операций. Операции можно перегружать добавлением в класс членов соответствующего им типа (которые обязательно должны быть статическими - static). Некоторые операции предусматривают несколько способов применения (как, например, операция -, у которой имеется как унарная, так и бинарная версия), поэтому при перегрузке операций также требуется указывать и то, о каком количество операндов идет речь и к какому типу эти операнды относятся. Как правило, тип операндов совпадает с типом класса, в котором определяется операция, хотя операции, способные работать со смешанными типами, тоже допускается определять, как будет показано чуть позже.

В качестве примера, давайте возьмем простой класс AddClassl, определенный следующим образом:

public class AddClassl {

public int val;

Oh представляет собой всего лишь оболочку вокруг значения int, но позволяет проиллюстрировать базовые принципы. С таким классом, показанный ниже код приведет во время компиляции к выдаче сообщения Об ошибке:

AddClassl opl = new AddClassl (); opl.val = 5;

AddClassl op2 = new AddClassl (); op2.val = 5;

AddClassl op3 = opl + op2;

В сообщении об ошибке говорится о том, что операция + не может применяться к операндам типа AddClassl. Объясняется это тем, что подлежащгш выполнению операция еще не была определена. Показанный ниже код будет работать, но не будет давать того результата, который, возможно, требуется:

AddClassl opl = new AddClassl (); opl.val = 5;

AddClassl op2 = new AddClassl ();

op2.val = 5;

bool op3 = opl == op2;

Здесь opl и op2 сравниваются с помощью бинарной операции == для выяснения того, ссылаются ли они на один и тот же объект, а не для выполнения проверки на предмет того, равны ли их значения. орЗ будет возвращать в предыдущем коде значение false, даже несмотря на то, что opl .val и ор2 .val идентичны.

Для перегрузки операции + можно использовать такой код:



public class AddClass2 {

public int val;

public class AddClassS {

public class AddClassl {

public int val; ,

public static AddClassl operator + (AddClassl opl, AddClassl op2) {

AddClassl returnVal = new AddClassl () ; returnVal.val = opl.val + op2.val; return returnVal;

Здесь видно, что перегрузки операций выглядят во многом подобно стандартным объявлениям статических методов, но только в них используется ключевое слово operator и сама операция, а не имя метода. Теперь операцию + можно успешно использовать с данным классом, как в предыдущем примере:

AddClassl орЗ = ор1 + ор2;

Перегрузка всех бинарных операций выполняется по одной и той же схеме. Унарные операции выглядят похоже, но имеют только один параметр:

public class AddClassl {

public int val;

public static AddClassl operator +(AddClassl opl, AddClassl op2) {

AddClassl returnVal = new AddClassl (); returnVal.val = opl.val + op2.val; return returnVal;

public static AddClassl operator - (AddClassl opl) {

AddClassl returnVal = new AddClassl () ; returnVal.val = -opl.val; return returnVal;

Обе эти операции работают с операндами того же типа, что и у класса, и имеют возвращаемые значения, тип которых тоже совпадает с типом данного класса. Теперь давайте возьмем, однако, такие определения классов:

public class AddClassl {

public int val;

public static AddClass3 operator +(AddClassl opl, AddClass2 op2) {

AddClassS returnVal = new AddClass3(); returnVal.val = opl.val + op2.val; return returnVal;



1 ... 97 98 99 [ 100 ] 101 102 103 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика