Why does foreach skip compile time type checking o

2019-04-08 00:09发布

问题:

When I use a foreach loop in C#, it appears that no compile time type checking is performed if the item type is an interface type.

E.g.

class SomeClass {}
interface SomeInterface {}

IEnumerable<SomeClass> stuff;
foreach(SomeInterface obj in stuff) { // This compiles - why!?
}

This will happily compile and cause an exception at runtime, when it is clear at compile time this makes no sense. If I change the item type from SomeInterface to another class, then compile time type-checking is restored:

IEnumerable<SomeClass> stuff;
foreach(Random obj in stuff) { // This doesn't compile - good!
}

Why is there no compile time type checks when the item type is an interface?

(This occurs with .NET 3.5 SP1 in Visual Studio 2008)

回答1:

It is NOT clear at compile time whether another part of the program, maybe in a different project, has:

class SomeOtherClass : SomeClass, ISomeInterface
{
   public static IEnumerable<SomeClass> GetSomeStuff()
   {
      for( int i = 0; i<10; ++i)
         yield return new SomeOtherClass(i);
   }
}

Now the runtime check SUCCEEDS.

If you mark SomeClass as sealed then this isn't possible, and it's again possible to know at compile time that the cast will never work.