I've just realised I'd written code that I'd expect to be invalid (with regard to syntax), but the compiler accepts.
For the sake of brevity I've recreated an example. Given a type:
private class MyType
{
}
I can then compare an instance of MyType
to an IEnumerable<MyType>
:
var myCollection = new List<MyType> { };
var test = new MyType() == (IEnumerable<MyType>)myCollection;
I'm surprised I can compare two objects of different types. Even more interesting (interesting to me at least), is if I remove the cast to IEnumerable
I can't compare it. Why is this the case? A List
implements IEnumerable
so assuming there's some kind of equality comparer somewhere that I'm missing (may be wrong), why isn't this available to List
, too?
Compiler is letting you compare objects to interfaces, but it doesn't let you compare them to unrelated concrete classes because it knows the precise type up-front and knows that the two types cannot be compared. Comparison to interface is allowed because a cast from the concrete object will be attempted at run time, and that is a valid operation per se.
What exactly are you going to do with that is a different story, and in fact none of your comparisons will be semantically correct.
In any case, your code does not produce a true comparison. It will return False
when run.
var test1 = new MyType() == (IEnumerable<MyType>)myCollection; // False
var test2 = new MyType() == new List<MyType>(); // Compile-time error
var test3 = new MyType() == (IComparable)5; // False
Another question is the use of ==
- which is wrong on another level. You are free to call Equals
as well, and seemingly attempt to perform true semantically meaningful comparison. Default implementation will not do anything meaningful, but again - looking from the compiler's point of view, everything is still syntactically correct.