Generics has undoubtedly made life a lot easier in the world of 1s and 0s and so this code snippet will only deal with the generics version since the code reads a lot easier. This is also a great bookmark post for future reference…
public class Foo { public string Alpha {get;set;} public string Omega {get;set;} }
This shouldn’t bother you too much, we just got Foo. Nice. But now we want to sort a bunch of instantiated Foos, as a “once-off” ascending, according to Alpha.
List<Foo> result = new List<Foo>(); . . results.Sort(delegate(Foo lhs, Foo rhs) { return lhs.Alpha.CompareTo(rhs.Alpha); });
Straightforward. Using the anonymous delegate to achieve that once-off without creating an unnecessary class. You might think you could do the same thing with BinarySearch.
Foo sample = new Foo{Alpha="a", Omega="z"}; results.BinarySearch(sample, delegate(Foo lhs, Foo rhs) { return lhs.Alpha.CompareTo(rhs.Alpha); });
But you can’t. In this case, you actually do need to create an unnecessary class.
Foo sample = new Foo{Alpha="a", Omega="z"}; srchIdx = results.BinarySearch(sample, new FooAlphaComparer()); . . . internal class FooAlphaComparer : IComparer<Foo> { public int Compare(Foo lhs, Foo rhs) { return lhs.Alpha.CompareTo(rhs.Alpha); } }
Same one liner in the Compare function, but this time, it has to be a class.
However (there’s always a BUT somewhere even if you call it a ‘however’), with a bit of kung-fu and ninja superpowers (apparently) there is a way to plumb this and make it work- but i tend to shift the complexity in other areas of the problem domain. It gets complicated. Moving right along…
For interest sake, you want to compare by Alpha AND Omega?
public int Compare(Foo lhs, Foo rhs) { int cfA = lhs.Alpha.CompareTo(rhs.Alpha); int cfO = lhs.Omega.CompareTo(rhs.Omega); if(0 != cfA) { //Alphas are not equal return cFA; } else if(0 != cfO) { return cf0; //Alphas are equal but Omegas aren't } else { return 0; //Alphas are equal and so are Omegas } }