Перегрузка унарных операторов — КиберПедия 

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

Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...

Перегрузка унарных операторов

2017-07-25 328
Перегрузка унарных операторов 0.00 из 5.00 0 оценок
Заказать работу

Возьмем программу с первого примера с деньгами, и перегрузим там унарные операторы «++», «--» (добавление/вычитание 1 единицы денег):

 

public class Money
{
public decimal Amount { get; set; }
public string Unit { get; set; }

public Money(decimal amount, string unit)
{
Amount = amount;
Unit = unit;
}
public static Money operator +(Money a, Money b)
{
if (a.Unit!= b.Unit)
throw new InvalidOperationException("Нельзя суммировать деньги в разных валютах");

return new Money(a.Amount + b.Amount, a.Unit);
}
public static Money operator ++(Money a) // перегрузка «++»
{
a.Amount++;
return a;
}
public static Money operator --(Money a) // перегрузка «--»
{
a.Amount--;
return a;
}

}
class Program
{
static void Main(string[] args)
{
Money myMoney = new Money(100, "USD");
myMoney++; // 101 USD
Console.ReadLine();
}
}

 

Также существует возможность перегрузки самого операторного метода. Это означает что в классе может быть несколько перегрузок одного оператора при условии что входные параметры будут отличаться типом данных (например, когда необходимо сложить объект класса и строку):

 

public class Money
{
public decimal Amount { get; set; }
public string Unit { get; set; }

public Money(decimal amount, string unit)
{
Amount = amount;
Unit = unit;
}
public static Money operator +(Money a, Money b)
{
if (a.Unit!= b.Unit)
throw new InvalidOperationException("Нельзя суммировать деньги в разных валютах");

return new Money(a.Amount + b.Amount, a.Unit);
}
public static string operator +(string text, Money a)
{
return text + a.Amount + " " + a.Unit;
}

}
class Program
{
static void Main(string[] args)
{
Money myMoney = new Money(100, "USD");
Console.WriteLine("У меня сейчас " + myMoney); // "У меня сейчас 100 USD"
Console.ReadLine();
}
}

 

Домашнее задание

Задание будет базироваться на примере в этом уроке. Необходимо реализовать второй вариант сложения денег – чтобы можно было суммировать деньги в разных валютах. Для этого создайте отдельный класс, который будет предоставлять механизм конвертации денег по заданному курсу. Кроме этого, перегрузите для класса Money оператор сравнения «==» (при перегрузке данного оператора, обязательной является и перегрузка противоположного ему оператора «!=»).

PS. Не забудьте поделиться с друзьями этой статьей с помощью кнопок социальных сетей.

Переопределение методов Equals и GetHashCode в Си-шарп. Разница между Equals и «==» Как известно, в Си-шарп все классы являются наследниками базового класса object. В нем есть три виртуальных метода – ToString, Equals и GetHashCode. В этом уроке мы поговорим с вами о последних двух методах, а также об операторе «==».

Скажу сразу, что вопрос разницы между оператором равенства «==» и методом Equals является классическим вопросом на собеседовании на вакансию программиста Си-шарп.

Оператор равенства «==»

По умолчанию при работе с ссылочными типами данных (все классы кроме string, интерфейсы, делегаты) оператор «==» проверяет равенство ссылок. Он возвращает true, когда обе ссылки указывают на один объект, в противном случае – false. Приведу код, который демонстрирует работу данного оператора с ссылочными типами:

 

static void Main(string[] args)
{
object o1 = new object();
object o2 = new object();
object o3 = o1;
Console.WriteLine(o1 == o2); // false
Console.WriteLine(o1 == o3); // true
}


Здесь создается два объекта, ссылки на которые записываются в переменные o1 и o2. Дальше ссылка o1 копируется в переменную o3 (o1 и o3 указывают на один объект). В итоге имеем false при сравнении ссылок o1 и o2, и true при o1 и o3.

Метод Equals

Метод Equals принимает один аргумент – объект, который будет сравниваться с текущим объектом, и определяет, равны ли между собой эти объекты. Здесь уже идет речь о равенстве полей объектов, а не ссылок. Этот метод виртуальный, и его базовая реализация это просто проверка равенства ссылок оператором «==». Но когда мы создаем некий класс, и нам необходимо реализовать возможность проверки идентичности объектов, следует переопределить именно данный метод, а не воспользоваться перегрузкой оператора «==», чтобы не спутывать базовые назначения этих инструментов сравнивания.

Перегрузка метода Equals

При переопределении метода Equals следует позаботиться о том, чтобы этот метод возвращал false в случаях, когда в метод передано значение NULL, когда переданный объект нельзя привести к типу текущего объекта, ну и когда поля объектов отличаются.

Возьмем уже знакомый нам класс Money с предыдущего урока, и переопределим в нем метод Equals:

 

public class Money
{
public decimal Amount { get; set; }
public string Unit { get; set; }

public Money(decimal amount, string unit)
{
Amount = amount;
Unit = unit;
}

public override bool Equals(object obj)
{
if (obj == null)
return false;
Money m = obj as Money; // возвращает null если объект нельзя привести к типу Money
if (m as Money == null)
return false;

return m.Amount == this.Amount && m.Unit == this.Unit;
}
}
class Program
{
static void Main(string[] args)
{
Money m1 = new Money(100, "RUR");
Money m2 = new Money(100, "RUR");
Money m3 = new Money(100, "USD");
Money m4 = m1;
Console.WriteLine(m1.Equals(m2)); // true
Console.WriteLine(m1.Equals(m3)); // false
Console.WriteLine(m1 == m2); // false
Console.WriteLine(m1 == m4); // true
Console.ReadLine();
}
}


Как видим, в коде выше метод Equals и оператор «==» работают соответственно своим базовым определениям.

Также для повышения производительности при переопределении метода Equals рекомендуется перегружать его реализацией с типом аргумента соответствующему классу, в котором он переопределяется:

 

public bool Equals(Money obj) // аргумент типа Money
{
if (obj == null)
return false;

return obj.Amount == this.Amount && obj.Unit == this.Unit;
}

 

Метод GetHashCode

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

- он должен возвращать одинаковый хеш-код каждый раз при вызове для одного и того же объекта.
- если имеется два равных (эквивалентных) объекта, то хеш-код для них должен быть одинаковым. Только это не означает, что если объекты неравны, то их хеш-коды обязательно будут разными.

Метод GetHashCode используется в таких структурах, как хэш-таблицы (Hashtable). Это мы сейчас рассматривать не будем, но корректность их работы стоит обеспечивать. Методы Equals и GetHashCode тесно связанны между собой, при переопределении одного из них, следует переопределять и другой. Базовая реализация метода GetHashCode в классе object очень условная, и она не обеспечивает второе свойство, когда одинаковые объекты имеют одинаковые хеш-коды.

 

static void Main(string[] args)
{
Money m1 = new Money(100, "RUR");
Money m2 = new Money(100, "RUR");
Console.WriteLine(m1.GetHashCode()); // 456...
Console.WriteLine(m2.GetHashCode()); // 411...
Console.ReadLine();
}


Чтобы это исправить, мы переопределяем метод GetHashCode, и возвращаем хеш-код каким-либо способом, зависящим от поля/полей объекта:

 

public class Money
{
public decimal Amount { get; set; }
public string Unit { get; set; }

public Money(decimal amount, string unit)
{
Amount = amount;
Unit = unit;
}

public override bool Equals(object obj)
{
if (obj == null)
return false;
Money m = obj as Money;
if (m as Money == null)
return false;
return m.Amount == this.Amount && m.Unit == this.Unit;
}
public bool Equals(Money obj) // аргумент типа Money
{
if (obj == null)
return false;
return obj.Amount == this.Amount && obj.Unit == this.Unit;
}
public override int GetHashCode()
{
int unitCode;
if (Unit == "RUR")
unitCode = 1;
else unitCode = 2;
return (int) Amount + unitCode;
}

}
class Program
{
static void Main(string[] args)
{
Money m1 = new Money(100, "RUR");
Money m2 = new Money(100, "RUR");
Money m3 = new Money(100, "USD");
Console.WriteLine(m1.GetHashCode()); // 101
Console.WriteLine(m2.GetHashCode()); // 101
Console.WriteLine(m3.GetHashCode()); // 102
Console.ReadLine();

}
}


Здесь в качестве хеш-кода возвращается количество денег (целая часть) плюс код валюты. В результате теперь второе условие выполняется.

Домашнее задание

Создайте класс окружность с полями координаты центра и радиус и переопределите в нем корректно методы Equals и GetHashCode. Окружности равны если у них одинаковые координаты центра и радиусы.

Регулярные выражения в Си-шарп. Класс Regex В этом уроке мы рассмотрим с вами очень мощный, широко используемый инструмент для обработки текста – регулярные выражения.

Регулярное выражение – это некий шаблон, составленный из символов и спецсимволов, который позволяет находить подстроки соответствующие этому шаблону в других строках. Спецсимволов и различных правил их комбинирования есть очень много, поэтому регулярные выражения можно даже назвать таким себе отдельным языком программирования. Те, кто пользовался поиском по файлам в Windows могут знать, что для того чтобы найти файлы только заданного расширения, задается шаблон типа «*.txt». Здесь «*» - спецсимвол, который означает любые имена файлов. Так вот регулярные выражения предоставляют подобный механизм.


Поделиться с друзьями:

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

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

История развития пистолетов-пулеметов: Предпосылкой для возникновения пистолетов-пулеметов послужила давняя тенденция тяготения винтовок...

История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.012 с.