PDA

View Full Version : مقاله: پیاده سازی IEqualityComparer برای حذف عناصر تکراری



Sajjad1364
یک شنبه 10 خرداد 1388, 04:06 صبح
با سلام
هدف من از ایجاد این تاپیک در این تالار این بود که این مقاله بیشتر با C# و کمی هم با Linq سروکار دارد. اما چون تالار دسترسی به داده ها زیاد در رابطه با Linq فعالیت ندارند ، شاید بهتر باشد این بحث اینجا مطرح شود.

صورت مسئله : چگونه باید عناصر تکراری را از Collection هایی که حاوی نوعی متفاوت از انواع اولیه هستند را حذف کنیم.

راه حل : با استفاده از متد Distinct و پیاده سازی مخصوصی از رابط :

IEqualityComparer<Student>

با استفاده از متد Distinct میتوان عناصر تکراری موجود در یک Collection را که حاوی داده های تکراری از انواع اولیه (.....,String,int,long,double,byte) هستند را حذف نمود اما اگر بخواهیم موضوع در مورد انواع ایجاد شده توسط یک توسعه دهنده صدق کند چکار باید کرد ؟
پاسخ پیاده سازی IEqualityComparer برای نوعی است که میخواهیم عملیات حذف عناصر تکراری روی آن انجام شود.

1- فرض می کنیم نوع داده Student راداریم که تعریف آن یصورت زیر است :


public class Student
{
public String Name { get; set; }
public long ID { get; set; }
}

2- در این مرحله باید کلاسی را تعریف کنیم که رابط IEqualityComparer را پیاده سازی میکند . این کلاس را StudentEquality نامگذاری میکنیم وپیاده سازی آن بصورت زیر است

public class StudentEquality:IEqualityComparer<Student>
{
#region IEqualityComparer<Student> Members

public bool Equals(Student x, Student y)
{
if (x.ID==y.ID)
{
return true;
}
else
{
return false;
}
}

public int GetHashCode(Student obj)
{
return 0;
}

#endregion
}
این نوع کلاس ها که برای پیاده سازی رابطی خاص در جهت انجام عملی خاص برروی شئ دیگری مورد استفاده قرار می گیرند را Helper Class می نامیم .
متد Equals دو پارامتر از نوع Student دریافت میکند و بدنه این متد شامل « الگوریتم مساوی بودن این دو شئ » میباشد ، میتوانید پیاده سازی ای که در کد بالا انجام شده است را ببینید.
.
اینطور فرض کنید که کامپایلر با استفاده از یک شئ از کلاس StudentEquality ، به متد Equals دو آرگومان از نوع Student میفرستد و الگوریتم شما موظف است وضعیت تساوی و یا عدم آنرا بررسی کند ، حالا الگوریتم و شرایط تساوی دو شئ Student از نظر شما چیست ؟ از نظر بنده حقیر مساوی بودن ID.

متد GetHashCode هم برای تولید HashCode مختص هر شئ Student میباشد که اینجا چون احتیاجی به پیاده سازی آن نداریم مقدار همیشگی 0 را برمی گردانیم.
رابط هایی که متدهای آنها در امضای خود از دو پارامتر استفاده میکنند معمولا و برای خوانایی بیشتر کد در Helper Class پیاده سازی میشوند.

در Main برنامه کد زیر را برای ایجاد تعدادی Student ایجاد میکنیم:

Student[] students = new Student[]
{
new Student(){Name="Ali",ID=2},new Student(){Name="Nader",ID=5},
new Student(){Name="Reza",ID=2},new Student(){Name="Morad",ID=3},
};
حالا باید از متد Distinct استفاده کنیم و بگوییم که پیاده سازی رابط :

IEqualityComparer<Student>
در کلاس StudentEquality ایجاد شده است یعنی برای حذف عناصر اضافه با توجه به ID ، از کلاس StudentEquality استفاده شود.

students.Distinct(new StudentEquality());
با نوشتن این کد دانش آموزی که نامش Reza بود حذف میشود ، چون ID او با ID ی Ali یکسان است.
نتیجه اینکه با استفاده از رابط IEqualityComparer و یک Helper Class بصورت سفارشی میتوان به حذف نتایج تکراری در Collection ها برپایه انواعی که یک توسعه دهنده ایجاد میکند ، مبادرت ورزید.

موفق باشید