IComparable<T> Vs. IComparer<T> System.Comparison<T>
Well they are not quite the same thing as IComparer<T>
is implemented on a type that is capable of comparing two different objects while IComparable<T>
is implemented on types that are able to compare themselves with other instances of the same type.
I tend to use IComparable<T>
for times when I need to know how another instance relates to this
instance. IComparer<T>
is useful for sorting collections as the IComparer<T>
stands outside of the comparison.
IComparer < T >是上实现一种能够比较两个不同的对象而IComparable < T >是上实现类型能够比较自己与其他相同类型的实例。
class Student : IComparable
{
public string Name { get; set; }
public int MathScore { get; set; }
public int EnglishScore { get; set; }
public int TotalScore
{
get
{
return this.MathScore + this.EnglishScore;
}
}
public int CompareTo(object obj)
{
return CompareTo(obj as Student);
}
public int CompareTo(Student other)
{
if (other == null)
{
return 1;
}
return this.Name.CompareTo(other.Name);
}
}
But if a teacher 'A' wants to compare students based on MathScore, and teacher 'B' wants to compare students based on EnglishScore. It will be good idea to implement IComparer separately. (More like a strategy pattern)
class CompareByMathScore : IComparer<Student>
{
public int Compare(Student x, Student y)
{
if (x.MathScore > y.MathScore)
return 1;
if (x.MathScore < y.MathScore)
return -1;
else
return 0;
}
}
- public class NameComparer:IComparer<Student>
- {
- public int Compare(Student x, Student y)
- {
- return x.Name.CompareTo(y.Name);
- }
- }
http://stackoverflow.com/questions/3498891/system-comparisont-understanding
System.Comparison<T>
is defined as follows:
public delegate int Comparison<in T>(T x, T y);
That means that it's delegate, not a class. A method accepting a delegate as a parameter actually accepts a method, not an instance of a Comparison class.
This code can be rewritten as follows with a lambda expression:
collection.Sort((i1, i2) => i1.ToString().CompareTo(i2.ToString()));
The following snippet might explain better what happens:
public static class TestClass {
public static void Main(string[] args){
Comparison<Int32> comparisonDelegate = CompareWithCase;
//We now can use comparisonDelegate as though it is a method;
int result = comparisonDelegate(1,2);
}
public static int CompareWithCase(int i1, int i2)
{
return i1.ToString().CompareTo(i2.ToString());
}
}