2016-01-18 65 views
-2

只是想了解C#。只是考慮下面的簡單例子。爲什麼這種隱式轉換不會導致編譯時錯誤?

void Main() 
{ 
    IList<IAnimal> animals = new List<IAnimal> 
    { 
     new Chicken(), 
     new Cow(), 
    }; 

    // Shouldn't this line result in a compile-time error? 
    foreach (Chicken element in animals) 
    { 
    } 
} 

public interface IAnimal 
{ 
} 

public class Cow : IAnimal 
{ 
} 

public class Chicken : IAnimal 
{ 
} 

儘管第一次迭代成功,但第二次迭代沒有成功。老實說,我預計這會在編譯時失敗。有誰知道它爲什麼只在運行時失敗?

+2

[回覆Eric Lippert](http://ericlippert.com/2013/07/22/why-does-a-foreach-loop-silently-insert-an-explicit-conversion/) –

+0

另請參閱:[爲什麼foreach循環默默插入「顯式」轉換?](http://ericlippert.com/2013/07/22/why-does-a-foreach-loop-silently-insert-an-explicit-conversion/)由Eric Lippert – Habib

+1

有人鏈接Eric Lippert關於此的帖子呢? – CodeCaster

回答

5

由於foreach語句在C# Language Specification定義爲具有(隱藏)顯式的轉換:

上述步驟,如果成功的話,毫無疑義地產生集合類型C,枚舉類型E和元素類型T.形式的foreach語句

foreach (V v in x) embedded-statement 

,然後擴大到:

{ 
    E e = ((C)(x)).GetEnumerator(); 
    try { 
     while (e.MoveNext()) { 
      V v = (V)(T)e.Current; 
      embedded-statement 
     } 
    } 
    finally { 
     … // Dispose e 
    } 
} 

(注意(V)(T)e.Current, 「顯式」 轉換爲類型V

它,不幸的是,這樣的定義,因爲這是你真正需要在C#1(仿製藥之前,其中你想要在foreach中迭代的每個集合都是object的集合),現在爲了向後兼容,它不能被更改。

相關問題