عملگر مقایسه ای SequenceEqual
در زبان کوئری نویسی LINQ فقط یک عملگر مقایسه ای وجود دارد که عملگر SequenceEqual نام دارد. این عملگر بررسی می کند که آیا عناصر موجود در دو مجموعه با هم برابر اند یا خیر. اگر مجموعه ها شامل مقادیری از نوع داده های Primitive (برای نمونه int, string, double, bool) باشند مقادیر عناصر با هم مقایسه می شود و اگر نوع داده پیچیده تری داشته باشند، reference عناصر بررسی می شود. در مثال زیر با استفاده از متد SequenceEqual دو مجموعه که از نوع داده آن ها string است با هم مقایسه می شوند:
1 2 3 4 | IList<string> strList1 = new List<string>(){"One", "Two", "Three", "Four", "Three"}; IList<string> strList2 = new List<string>(){"One", "Two", "Three", "Four", "Three"}; bool isEqual = strList1.SequenceEqual(strList2); // returns true Console.WriteLine(isEqual); |
توجه داشته باشید که برای متد SequenceEqual ترتیب عناصر مهم است و اگر ترتیب دو مجموعه یکی نباشید نتیجه false خواهد بود. مثال:
1 2 3 4 | IList<string> strList1 = new List<string>(){"One", "Two", "Three", "Four", "Three"}; IList<string> strList2 = new List<string>(){ "Two", "One", "Three", "Four", "Three"}; bool isEqual = strList1.SequenceEqual(strList2); // returns false Console.WriteLine(isEqual); |
در هنگام مقایسه دو مجموعه که نوع داده پیچیده تری دارند، متد افزودنی SequenceEqual برای مقایسه عناصر از reference آن ها استفاده می کند. این موضوع ممکن است نتیجه اشتباه تولید کند. برای مثال:
1 2 3 4 5 6 7 8 9 | Student std = new Student() { StudentID = 1, StudentName = "Bill" }; IList<Student> studentList1 = new List<Student>(){ std }; IList<Student> studentList2 = new List<Student>(){ std }; bool isEqual = studentList1.SequenceEqual(studentList2); // returns true Student std1 = new Student() { StudentID = 1, StudentName = "Bill" }; Student std2 = new Student() { StudentID = 1, StudentName = "Bill" }; IList<Student> studentList3 = new List<Student>(){ std1}; IList<Student> studentList4 = new List<Student>(){ std2 }; isEqual = studentList3.SequenceEqual(studentList4);// returns false |
در مثال فوق studentList1 و studentList2 هر دو یک عنصر دارند که همان شیء std است یعنی reference آن ها برابر است. در نتیجه این دو مجموعه برابر اند. اما stdList1 و stdList2 از دو شیء متفاوت تشکیل شده اند و این موضوع باعث می شود تا نتیجه false شود با این که مقادیر هر دو شیء یکسان است.
برای رفع این مشکل می توانیم از اینترفیس IEqualityComperar
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class StudentComparer : IEqualityComparer<Student> { public bool Equals(Student x, Student y) { if (x.StudentID == y.StudentID && x.StudentName.ToLower() == y.StudentName.ToLower()) return true; return false; } public int GetHashCode(Student obj) { return obj.GetHashCode(); } } |
با استفاده از اینترفیس می توانیم یک مقایسه کننده سفارشی ایجاد کرده و از آن برای مقایسه دو مجموعه استفاده کنیم. برای درک بهتر به مثال زیر توجه کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | IList<Student> studentList1 = new List<Student>() { new Student() { StudentID = 1, StudentName = "John", Age = 18 } , new Student() { StudentID = 2, StudentName = "Steve", Age = 15 } , new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } , new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } , new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 } }; IList<Student> studentList2 = new List<Student>() { new Student() { StudentID = 1, StudentName = "John", Age = 18 } , new Student() { StudentID = 2, StudentName = "Steve", Age = 15 } , new Student() { StudentID = 3, StudentName = "Bill", Age = 25 } , new Student() { StudentID = 4, StudentName = "Ram" , Age = 20 } , new Student() { StudentID = 5, StudentName = "Ron" , Age = 19 } }; // following returns true bool isEqual = studentList1.SequenceEqual(studentList2, new StudentComparer()); |
It is so useful page thank you