2010-08-02 3 views
6

Когда я использую цикл foreach на C#, кажется, что проверка типа времени компиляции не выполняется, если тип элемента является типом интерфейса.Почему foreach пропускает проверку типа времени компиляции типов интерфейсов?

E.g.

class SomeClass {} 
interface SomeInterface {} 

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

Это будет счастливо компилировать и вызвать исключение во время выполнения, когда станет ясно, во время компиляции это не имеет никакого смысла. Если изменить тип элемента из SomeInterface к другому классу, то во время компиляции типа проверки восстанавливается:

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

Почему же нет компиляции проверяет тип времени, когда тип элемента представляет собой интерфейс?

(Это происходит с .NET 3.5 SP1 в Visual Studio 2008)

+0

Да, я задавался вопросом (и был укушен) тем же самым. С нетерпением ждем ответов от тех, кто знает! – Eyvind

ответ

8

Это не ясно, во время компиляции ли, может быть, в другом проекте, есть другая часть программы:

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

Теперь проверка времени исполнения SUCCEEDS.

Если вы отметите SomeClass как sealed, тогда это невозможно, и это снова можно узнать во время компиляции, что актеры никогда не будут работать.

+0

Что вы говорите правильно. Я удивлен, что C# использует этот подход с «foreach», поскольку он делает язык непоследовательным. Например, вызовы методов не имеют такого же поведения. – pauldoo

+0

+1 ПРОВЕРЕННЫЙ ответ. Не думал об этом раньше. –

+0

Это не противоречиво, это то же поведение, что и кастинг, подумайте: 'foreach (SomeClass obj in stuff) ((ISomeInterface) obj) .SomeInterfaceMethod();' –

 Смежные вопросы

  • Нет связанных вопросов^_^