Why does C# allow for the implicit conversion of an object to an int for equality comparison, but not for an object type to object type comparison, even though an implicit operator exists?
The bool errorHere = valueOnly == valuePair; line gives the exception at the bottom.
class Program
{
static void Main(string[] args)
{
ValueOnly valueOnly = new ValueOnly();
ValuePair valuePair = new ValuePair();
bool areEqual = valueOnly.Value == valuePair;
bool errorHere = valueOnly == valuePair;
bool butNotHere = valueOnly == (ValueOnly)valuePair;
valueOnly = valuePair; // Or Here
}
}
public class ValuePair
{
public int Value { get; set; }
public string Text { get; set; }
public static implicit operator ValueOnly(ValuePair valuePair) {
if (valuePair.Text != null || valuePair.Value != 0) {
return new ValueOnly() { Value = valuePair.Value };
}
return null;
}
public static implicit operator int(ValuePair valuePair) {
return valuePair.Value;
}
}
public class ValueOnly
{
public int Value { get; set; }
}
Here is the error:
Error Operator '==' cannot be applied to operands of type 'ValueOnly' and 'ValuePair'
C# most certainly does not allow implicit conversions of objects to
ints for any purpose. I ‘m not sure if you are referring to the lineas “allowing” such a conversion. If so, it does not do any such thing. It simply invokes your own conversion operator (which if I read the code correctly will return
nullsince the value will be a default-constructed integer) and then does a reference comparison between the two objects (which evaluates tofalseasnullis not reference-equal to anything).It also goes without saying that once you define an implicit conversion operator C# will use it whenever it is necessary. Therefore I think your question has to do more with understanding how the equality operator works based on the types of its arguments than anything else.
Update, regarding the
valueOnly == valuePaircheck:The C# specification, 7.10.6 (Reference type equality operators) states:
If you want to be able to compare objects of class type for equality, the best way is to implement the
IEquatable<T>interface, and overrideobject.Equalsto be implemented in terms ofIEquatable<T>.Equals(this means that you will also have to overrideobject.GetHashCode) to match.However, it’s a bad idea to rely on “hidden” conversions when comparing items. If we ‘re talking about comparing unrelated classes, you will save yourself a lot of anguish down the road by making the comparison as prominent as possible. To that end, I would suggest the low tech