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.

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

}<br />

result = result * prime + y.GetHashCode();<br />

result = result * prime + z.GetHashCode();<br />

}<br />

}<br />

return result;<br />

Тази имплементация е несравнимо по-добра от това да не правим нищо или<br />

да връщаме константа. Въпреки това колизиите и при нея се срещат, но<br />

доста по-рядко.<br />

Интерфейсът IEqualityComparer<br />

Едно от най-важните неща, които разбрахме досега е, че за да ползваме<br />

инстанциите на даден клас като ключове за речник, то класът трябва да<br />

имплементира правилно GetHashCode и Equals. Но какво да направим, ако<br />

искаме да използваме клас, който не можем или не искаме да наследим или<br />

променим? В този случай на помощ идва интерфейсът<br />

IEqualityComparer. Той дефинира следните две операции:<br />

bool Equals(T obj1, T obj2) – връща true ако obj1 и obj2 са равни<br />

int GetHashCode(T obj) – връща хеш-кода за дадения обект.<br />

Вече се досещате, че речниците в .NET могат да използват инстанция<br />

на IEqualityComparer, вместо съответните методи на класа даден за ключ.<br />

По този начин разработчиците могат да ползват практически всеки клас за<br />

ключ на речник, стига да осигурят имплементация на IEqualityComparer за<br />

този клас. Дори нещо повече - когато предоставим IEqualityComparer на<br />

речник, можем да променим начина, по който се изчислява GetHashCode и<br />

Equals за всякакви типове, дори за тези в .NET, тъй като в този случай<br />

речника използва методите на интерфейса вместо съответните методи на<br />

класа ключ. Ето един пример за имплементация на IEqualityComparer, за<br />

класа Point3D, който разгледахме по-рано:<br />

public class Point3DEqualityComparer : IEqualityComparer<br />

{<br />

#region IEqualityComparer Members<br />

public bool Equals(Point3D point1, Point3D point2)<br />

{<br />

if (point1 == point2)<br />

return true;<br />

if (point1 == null || point2 == null)<br />

return false;<br />

if (!point1.X.Equals(point2.X))

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

Saved successfully!

Ooh no, something went wrong!