Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why comparing a single element against an IEnumerable is not a compilation error

Tags:

c#

ienumerable

var fooRef = new FooRef();
var fooRefEnumerable = Enumerable.Empty<FooRef>();

var fooRefEquality = (fooRef == fooRefEnumerable); //This compiles without any errors

var fooVal = new FooVal();
var fooValEnumerable = Enumerable.Empty<FooVal>();

//Compilation error : Error 1 Operator '==' cannot be applied to operands of type 'FooVal' and 'System.Collections.Generic.IEnumerable<FooVal>'
var fooValEquality = (fooVal == fooValEnumerable); 

public class FooRef { }
public struct FooVal { }   

Why is it comparing a single object and an IEnumerable valid for RefTypes?

like image 731
Nasmi Sabeer Avatar asked Mar 18 '14 18:03

Nasmi Sabeer


1 Answers

Why is it comparing a single object and an IEnumerable is valid for RefTypes?

Because it's entirely feasible that it will return true:

class CunningFooRef : FooRef, IEnumerable<FooRef>
{
    // Implementation...
}

FooRef fooRef = new CunningFooRef();
IEnumerable<FooRef> fooRefEnumerable = Enumerable.Empty<FooRef>();
Console.WriteLine(fooRef == fooRefEnumerable); // False

fooRefEnumerable = (IEnumerable<FooRef>) fooRef;
Console.WriteLine(fooRef == fooRefEnumerable); // True

Note that this is using the same compile-time types for fooRef and fooRefEnumerable as you're using.

If you seal FooRef, so the compiler knows that it's impossible for a FooRef reference to also be an IEnumerable<FooRef> reference, then you'll get a compile-time error.

like image 56
Jon Skeet Avatar answered Nov 08 '22 22:11

Jon Skeet