compare when it be able to compare, but not when the grammar allow it to compare

Coordinator
Feb 18, 2014 at 4:41 PM
it's similar as cast, the runtime compare is also a problem in generic programming.
say you have two collections, aka vector<T>, the elements in the collection do not must have IComparable<T> implemented. but in some scenarios, surely you know these kind of scenarios, the elements are comparable. then the collections are comparable. i.e. vector<not_comparable_class> instances are not comparable, but vector<int> instances are comparable. at least you can compare vector<int> A with vector<int> B by the element in the collection.
but since the T does not have the IComparable<T> constraint, you can not write a compare function in the implementation of vector<T>, then what to do? write a vector_not_comparable_class, a vector_int, a vector_string ... it's ugly, the duplicate code will make the whole system not maintainable.

so in https://geminibranch.codeplex.com/SourceControl/latest#osi/root/connector/compare.vb, there is a compare function, it can help to compare any two types without constraint. it only needs you to know whether the two types at runtime are indeed comparable.
the prototype is
int compare<T1, T2>(T1 this, T2 that);
bool compare<T1, T2>(T1 this, T2 that, ref int o);
the second will return true when compare successful, return false when fail. fail means there is no compare function implemented between these two types. when success, the o will be the compare result, similar as stl design, <0 means this < that, >0 means this > that, =0 means this = that.
the first will return a random magic number as compare_error_result when compare failed, otherwise the result meaning is same as the second implementation.

the step of the function is,
  1. object compare, whether two objects are null, if both are null, they are equal, if one of them is null, the other is larger. otherwise, go on to next step.
  2. decide whether we need to use runtime compare, runtime compare is trying to find IComparable<T> / IComparable implementation in both types, while the decide logic depends on the types input as T1 / T2. if we do not need to use runtime compare, go on to the next step, otherwise return the runtime compare result.
  3. cached compare function, the IComparable<T> / IComparable implementation has been selected already for the two types input, so we do not need to use reflection to find it again, directly call the function will return the compare result.
also similar as cast, the compare unit test https://geminibranch.codeplex.com/SourceControl/latest#osi/root/tests/connector/compare_test.vb shows the scenarios supported. include but not only,
all the .net internal types
user defined types with IComparable<OtherType> implemented
nullable<T>