25.07.2017 Views

Intro-CSharp-Book-v2015

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

746 Въведение в програмирането със C#<br />

един и същ. Така полетата, които не участват в пресмятането на Equals(),<br />

не трябва да участват и в изчисляване на GetHashCode().<br />

След като сме определили полетата, които ще участват в изчислението на<br />

GetHashCode(), трябва по някакъв начин да получим за тях стойности от тип<br />

int. Ето една примерна схема:<br />

- Ако полето е bool, за true взимаме 1, а за false взимаме 0 (или<br />

директно викаме GetHashCode() на bool).<br />

- Ако полето е от тип int, byte, short, char можем да го преобразуваме<br />

към int, чрез оператора за явно преобразуване (int) (или директно<br />

викаме GetHashCode()).<br />

- Ако полето е от тип long, float или double, можем да ползваме<br />

наготово резултата от техните GetHashCode().<br />

- Ако полето не е от примитивен тип, просто извикваме метода<br />

GetHashCode() на този обект. Ако стойността на полето е null,<br />

връщаме 0.<br />

- Ако полето е масив или някаква колекция, извличаме хеш-кода за<br />

всеки елемент на тази колекция.<br />

Накрая сумираме получените int стойности, като преди всяко събиране<br />

умножаваме временния резултат с някое просто число (например 83), като<br />

игнорираме евентуалните препълвания на типа int.<br />

В крайна сметка получаваме хеш-код, който е добре разпределен в пространството<br />

от всички 32-битови стойности. Можем да очакваме, че при така<br />

изчислен хеш-код колизиите ще са рядкост, тъй като всяка промяна в<br />

някое от полетата, участващи в описаната схема за изчисление, води до<br />

съществена промяна в хеш-кода.<br />

Имплементиране на GetHashCode() – пример<br />

Да илюстрираме горният алгоритъм с един пример. Нека имаме клас, чиито<br />

обекти представляват точка в тримерното пространство. И нека точката<br />

вътрешно представяме чрез нейните координати по трите измерения x, y и<br />

z:<br />

Point3D.cs<br />

/// <br />

/// Class representing a point in three dimensional space.<br />

/// <br />

public class Point3D<br />

{<br />

private double x;<br />

private double y;<br />

private double z;

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!