2012-02-21 211 views
3

是這樣的可能在C#中?繼承與C#泛型,而類繼承類型

假設我有這樣的:

public class T : U 
{ 
... 
} 

,我想這一點:

public class A<T> : B<U> 
{ 
... 
} 

,這樣我可以在我的代碼有這樣的:

B<U> x = new A<T>(); 

回答

0

這是不完全清楚你要做什麼(班級名稱沒有幫助,我的大腦正在與T級奮鬥)。是羅伊Dictus的回答你想要的,或者也許克里斯的答案是你在找什麼?我解釋這個問題以不同的方式從任前的,像這樣的

public class MyBaseClass {} 

    public class MyClass : MyBaseClass {} 

    interface IB<out T>{} 

    public class B<T> : IB<T> { } 

    public class A<T> : B<T> {} 

    static void Main(string[] args) 
    { 
     IB<MyBaseClass> myVar = new A<MyClass>(); 
    } 

的關鍵在於interfaces support covariance, classes do not

2

你不能把它完全像你寫的,但你可以這樣做:

public class A<T, U> : B<U> where T : U 
{ 
    ... 
} 

然後做

B<U> x = new A<T, U>(); 
+0

他可以完全按照他所寫的來寫,它可能並不意味着他想要的。但是,如果他願意,他可以準確地輸入他認爲有效的C#的內容。 :) – Chris 2012-02-21 16:22:15

+0

好的,我寫的並不完全是我的意思:) – jambodev 2012-02-22 08:17:07

1

那最初的代碼沒有正常工作......雖然有可能由於您使用的術語而有些混淆......

我相信您寫的代碼可以更清晰地改寫如下:

void Main() 
{ 
    B<Foobar> x = new A<Wibble>(); 

} 

// Define other methods and classes here 
public class Foobar 
{ 
} 

public class Wibble : Foobar 
{ 
} 

public class B<U> 
{ 
} 

public class A<T> : B<Foobar> 
{ 
} 

關鍵要注意的是,有時候您在泛型參數的上下文中使用U,有時您將它用作具體類。

上面的代碼是等效(在IL的字詞LINQPad它編譯到)到:

void Main() 
{ 
    B<U> x = new A<T>(); 

} 

// Define other methods and classes here 
public class U 
{ 
} 

public class T : U 
{ 
} 

public class B<U> 
{ 
} 

public class A<T> : B<U> 
{ 
} 

只有最後兩個類使用通用參數和的最後一個類不具有u定義爲泛型參數,所以它將它視爲具體類。很難說這是否是你想要的,因爲你沒有告訴我們你想要什麼,只是給我們展示了一些代碼。我想可能你想要兩個通用參數解決方案,如@Roy Dictus所回答的,但你可能需要這樣做。它很難說。 ;-)

我應該注意到,我將這個答案部分歸功於之前被刪除的答案。該答案指出,編寫的代碼很好,這啓發了我測試實際代碼。不幸的是,在回答被刪除的問題上,我無法將有關人士稱爲靈感。

謝謝大家。 Chris解決了我的問題,前提是我可以在以下構造函數A<T>中調用構造函數T:public class A<T>B<Foobar> {}我該怎麼做? - jambodev 1分鐘前

在這種情況下,T是一個通用參數,所以你必須告訴編譯器T是絕對可構造的。要做到這一點,你需要約束T來確保它有一個構造函數。那麼你應該可以隨時創建它的新實例(例如:T foo = new T();

你當然不能用與鏈接基類的構造函數相同的方式來調用構造函數,因爲A並不是從T中派生出來的方式,它只是使用類型T的對象在其通用圖案。

public class A<T> : B<Foobar> where T :new() 
{ 
    public T MyInstance {get; set;} 
    public A() 
    { 
     MyInstance = new T(); 
    } 
} 

void Main() 
{ 
    B<Foobar> x = new A<Wibble>(); 
    Wibble y = ((A<Wibble>)x).MyInstance; 
} 

(此代碼替換從我的第一碼塊中的等效方法)

注意,y是類型維布勒的目的所創建在x的conscructor中。還請注意,在訪問它之前我需要投射x,因爲B<Foobar>對使用​​通用類型Wibble一無所知。

+0

謝謝大家。 克里斯這個解決我的問題只要我能夠調用的T構造在下方的的構造函數: 公共類A :乙 {} 我怎麼能這樣做? – jambodev 2012-02-21 17:32:35

+0

我已經在我的答案更新中回答了您的問題。 – Chris 2012-02-21 17:48:02

+0

再次感謝克里斯。 – jambodev 2012-02-21 18:19:15