2011-11-10 50 views
8

可能重複:
Foreach can throw an InvalidCastException?爲什麼編譯器會讓這個滑動?

考慮下面的代碼塊

public class Base 
{ 
} 

public class DerivedLeft : Base 
{ 
} 

public class DerivedRight : Base 
{ 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<Base> list = new List<Base> { new DerivedLeft(), new DerivedRight() }; 
     foreach (DerivedLeft dl in list) 
     { 
      Console.WriteLine(dl.ToString()); 
     } 
    } 
} 

通知劇組從基地到DerivedLeft在foreach語句。這編譯好(Visual Studio 2010),沒有任何錯誤或甚至警告。 顯然,在第二次循環迭代中,我們將得到一個InvalidCastException。 如果有人問我關於編譯器對這些代碼的反應的問題,我毫無疑問地說,編譯器不會讓這個問題不被注意到,並且至少會產生一個警告。 但顯然它沒有。那麼,爲什麼編譯器會讓這個漏洞通過?

回答

2

因爲名單是List<Base>類型,並在foreach循環變量dl的類型DerivedLeft擁有基地的基類。所以它可以運行期間工作,但它不到。編譯器不檢查列表的初始化。

+0

我覺得編譯器檢查初始化.... e.g。如果我把MyOtherClass放在那裏,所以有編譯時異常 –

+0

@RoyiNamir:是的,編譯器檢查初始化是否正確,但它不檢查當他到達foreach循環時是否只有匹配的元素。 – Fischermaen

+0

正確............ –

0

期待編譯器在此產生一個錯誤就像是期待它在這引發錯誤:

Base b = new DerivedRight(); 
DerivedLeft d = (DerivedLeft)b; 
+0

事實上編譯器會在這裏提出一個錯誤,因爲你沒有提供DerivedLeft的變量名稱:) – Trogvar

+0

true ......... :) – nogola

+0

公平地說,涉及'foreach'的隱式轉換並沒有那麼明顯,除非已經用.NET C#編寫了.NET1.0或1.1,其中缺乏泛型意味着不會有隱式轉換,因爲每個「foreach」都沒有'處理'對象'將需要一個。 –