I am wondering why the code like this won't work:
public static bool cmp <T> (T a, T b)
{
return a == b;
}
I assume, that there should be an IComparable
constraint added, to make it work (maybe CompareTo
instead of ==
as well). With class
constraint, references would be compared. With struct
constraint, no comparison is allowed, as well as with no constraint.
Wouldn't it be possible to resolve given type and compare references in case when object is passed, and compare values when the value types are passed?
C# provides an IComparable interface. This interface provides different types of type-specific comparison methods which means a value type or a class can implement this interface to sort its instances because we cannot sort the instances of a class directly because the compiler does not know on which basis to sort.
If you need to compare objects of type T by more or less, then the IComparable<T> interface will do. Such a comparison is necessary, for example, when sorting. If you need to compare objects of type T for equality/inequality, you can use the IEquatable<T> interface.
There is a remark in the language specification.
Take a look at paragraph 7.10.6:
The predefined reference type equality operators do not permit value type operands to be compared. Therefore, unless a struct type declares its own equality operators, it is not possible to compare values of that struct type.
Structs cannot be compared with ==
, because this operator is not defined for every value type.
The standard explicitly mentions integer types, floats, decimals, booleans and enumerations, and of course reference types.
So it is not possible by design. And why?
It makes sense. Intuition tells us that a value type should be compared by value. So two value type variables are equal, if they have the same content. Although a struct is a blob of data, it may contain references to objects. If this references differ, but have the same value, what should be the result of such a comparison?
For example:
public struct A
{
public string S;
}
A a;
A b;
a.S = "Hello";
b.S = "Hello world".Split(' ')[0]; //to avoid reusing the same reference, probably ;]
var result = (a == b);
What should be the answer? Binary they are different, but values are the same.
There is always ValueType.Equals, overloaded from object.Equals
, that tries to address this problem. It performs the value comparison where possible and reference comparison where not. But you have to keep in mind, that it makes a struct kinda bloated. You have a default operation on every struct, that could take ages to complete. So it is possible, but not as a struct's functionality per se.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With