cả hai giao diện dường như so sánh các đối tượng để bình đẳng, vậy sự khác biệt chính giữa chúng là gì?
cả hai giao diện dường như so sánh các đối tượng để bình đẳng, vậy sự khác biệt chính giữa chúng là gì?
Câu trả lời:
IEquatable<T>
vì sự bình đẳng.
IComparable<T>
Để đặt hàng.
Ngoài câu trả lời của Greg D:
Bạn có thể triển khai IComparable
mà không triển khai IEquatable
cho một lớp mà thứ tự một phần có ý nghĩa và nơi bạn chắc chắn muốn người tiêu dùng suy luận rằng chỉ vì CompareTo()
trả về 0, điều này không có nghĩa là các đối tượng là bằng nhau (cho bất kỳ điều gì khác ngoài mục đích sắp xếp).
IComparable
hoàn toàn không phù hợp ở đây. Những gì bạn có là một thứ tự rất đặc biệt chỉ áp dụng trong một tình huống đặc biệt. Đối với những tình huống như vậy, việc triển khai một vị tướng IComparable
là sai lầm. Đây là những gì IComparer
có ở đó. Ví dụ, mọi người không thể được sắp xếp một cách có ý nghĩa. Nhưng họ có thể được đặt hàng tùy theo mức lương, cỡ giày, số lượng tàn nhang hoặc trọng lượng của họ. Do đó, chúng tôi sẽ triển khai các IComparer
s khác nhau cho tất cả các trường hợp này.
Như đã nêu trên Trang MSDN cho IEquatable :
Giao diện IComp so sánh định nghĩa
CompareTo
phương thức, xác định thứ tự sắp xếp của các thể hiện của kiểu triển khai. Giao diện IEquatable xác địnhEquals
phương thức, phương thức này xác định sự bình đẳng của các thể hiện của kiểu triển khai.
Equals
so với CompareTo
IComparable <T>
xác định một phương pháp so sánh cụ thể kiểu có thể được sử dụng để sắp xếp hoặc sắp xếp các đối tượng.
IEquatable <T>
xác định một phương pháp tổng quát có thể được sử dụng để thực hiện để xác định bình đẳng.
Giả sử bạn có lớp Người
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
Person p1 = new Person() { Name = "Person 1", Age = 34 };
Person p2 = new Person() { Name = "Person 2", Age = 31 };
Person p3 = new Person() { Name = "Person 3", Age = 33 };
Person p4 = new Person() { Name = "Person 4", Age = 26 };
List<Person> people = new List<Person> { p1, p2, p3, p4 };
people.Sort();
.Nhưng điều này sẽ ném ra một ngoại lệ.
Framework không biết cách sắp xếp các đối tượng này. Bạn cần biết cách sắp xếp IComparable
giao diện thực thi .
public class Person : IComparable
{
public string Name { get; set; }
public int Age { get; set; }
public int CompareTo(object obj)
{
Person otherPerson = obj as Person;
if (otherPerson == null)
{
throw new ArgumentNullException();
}
else
{
return Age.CompareTo(otherPerson.Age);
}
}
}
Điều này sẽ sắp xếp mảng đúng với Sort()
phương thức.
Equals()
phương pháp.var newPerson = new Person() { Name = "Person 1", Age = 34 };
var newPersonIsPerson1 = newPerson.Equals(p1);
Điều này sẽ trả vềfalse
vì Equals
phương thức không biết cách so sánh hai đối tượng. Do đó, bạn cần phải triển khai IEquatable
giao diện và cho khung làm việc so sánh như thế nào. Mở rộng trên ví dụ trước, nó sẽ giống như thế này.
public class Person : IComparable, IEquatable<Person>
{
//Some code hidden
public bool Equals(Person other)
{
if (Age == other.Age && Name == other.Name)
{
return true;
}
else
{
return false;
}
}
}
IEquatable
sử dụng chung chung <Person>
và IComparable
không sử dụng ?
IComparable
đúng cách. Bạn có thể đưa ra một ví dụ đầy ý nghĩa nơiCompareTo(…) == 0
nào không bao hàm sự bình đẳng? Tôi chắc chắn không thể. Trên thực tế, hợp đồng giao diện (theo MSDN) yêu cầu phải cóCompareTo(…) == 0
nghĩa là bình đẳng. Nói trắng ra, trong trường hợp như của bạn, hãy sử dụng mộtComparator
đối tượng đặc biệt , không nên thực hiệnIComparable
.