2010-11-10 128 views
6

我有兩個接口:C#繼承問題

public interface A { 
void aMethod(); 
} 


public interface B : A { 
void bMethod(); 
} 

後來我基本上使用的字典是這樣的:

Dictionary<int, A> dict = new Dictionary<int, B>(); 

C#是說我不能向右轉換左邊,即使我投了它。有沒有辦法在C#中使用泛型,以便這可以工作?如果我讓他們抽象類似乎沒問題,但我需要這些作爲接口。

+1

您使用的是什麼版本的.NET? – Dinah 2010-11-10 16:45:45

+0

@Dinah:爲什麼在這種情況下框架版本會有所作爲? – LukeH 2010-11-10 17:27:10

+0

@LukeH:因爲.NET 4.0有可能解決這個問題的協方差和反方差。如果dmurph儘管在4.0版本中有這個問題,問題將會與4.0之前發生的問題有所不同 – Dinah 2010-11-10 17:40:29

回答

7

不是這是一個協變問題。如果你可以做:

Dictionary<int, A> dict = new Dictionary<int, B>(); 

這將有可能沒有一個編譯器錯誤把一個類型的對象字典。

問題是字典的樣子:Dictionary<int, A>,但它確實是鍵入Dictionary<int, B>()(這樣,將一個類型的對象,將拋出,因爲無效的轉換的運行時錯誤),所以你不應該被允許甚至試圖將一個類型的對象字典,這就是爲什麼你不能這樣做:

Dictionary<int, A> dict = new Dictionary<int, B>(); 

它保護你進行一個運行時錯誤。
你想看看Eric Lippert關於這個問題的博客:http://blogs.msdn.com/b/ericlippert/

這是他最喜歡談論的話題之一,所以它是相當徹底的。

+0

感謝您的博客鏈接!這是有道理的 – 2010-11-13 00:49:21

0

我不認爲你會找到解決問題的辦法,因爲背後的想法似乎有缺陷。爲了說明這一點,讓我們創建另一個接口:

public interface C : A 
{ 
    void cMethod(); 
} 

現在,讓我們用你的代碼:

Dictionary<int, A> dict = new Dictionary<int, B>(); 

會發生什麼事,當我嘗試以下方法?

C c = new ClassThatImplementsC(); 
dict.Add(1, c); 

看看Eric Lippert's Covariance and Contravarience FAQ瞭解很多很多細節。

+1

這實際上是亞歷山德拉的常見問題;我剛剛編輯它。 – 2010-11-11 07:22:01

+0

這也使很多道理,謝謝 – 2010-11-13 00:49:50