Основне меню  

   

Реклама  

Скачуйте відеуроки для створення сайту за допомогою SMS Joomla 

реклама

 

 

   

Ми в Facebook  

Калькулятор расчета пеноблоков смотрите на этом ресурсе
Все о каркасном доме можно найти здесь http://stroidom-shop.ru
Как снять комнату в коммунальной квартире смотрите тут comintour.net
   

З Новим роком!  

   

Статистика  

Користувачі
1
Статті
171
Перегляди статей
447255
   

Пошук по сайту  

   

Ми знаходимось тут  

   

Випадкове фото  

   

Наш відеоканал  

   

Відвідування сайту  

Яндекс.Метрика

 

   

Посібник Delphi  

ДОСТУПНИЙ ВИКЛАД,

ЦІКАВІ ПРИКЛАДИ, ВИХІДНІ КОДИ.

ЦІНА ДИСКА З МАТЕРІАЛАМИ - 500 грн. 

Якщо ваша карта обслуговується ПриватБанком тоді переведіть потрібну суму через Приват24 на карту    5168 7573 0556 9925 або натисніть на посилання "Перейти до оплати", щоб здійснити миттєвий платіж без комісії. Перейти до оплати!

 Звертайтесь за адресою еmail:kuzbyt@ukr.net

 
   

Відеокурс по С++  

   

Рекомендуємо:  

   

Ми в контактах  

   

Сайти  

Українські уроки про ІТ

Єдина Країна! Единая Страна!

 

Українські уроки про програмування

 

 
   

Як відомо, в Сі-Шарп всі класи є спадкоємцями базового класу 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, "UA");

     Money m2 = new Money (100, "UA");

     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, "UA");

   Money m2 = new Money (100, "UA");

   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, "UA");

     Money m2 = new Money (100, "UA");

     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. Кола рівні якщо у них однакові координати центру і радіуси.

 

   

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

 
   

Сайт для перевірки своїх знань з програмування на сайті:http://www.quizful.net/test


 Розробка сайтів, інтернет-магазинів під ключ. Створення програмного забезпечення для обліку в магазинах,

гуртовнях, ведення власного бізнесу та інших. Написання дипломних та курсових робіт з програмування, баз даних.

 

Звертайтесь за адресою email:kuzbyt@ukr.net

 

 

© (C) Sambir, I.Kuzbyt