2011-12-02 86 views
0

我有一套類和接口有一個相對簡單的層次結構,但有東西繼承,然後有一個接受基類的變量工作不正常。我認爲問題在於我的動態類型必須爲where : class而不是where : IEntity,因爲這些類型用於我無法更改的功能。C#將派生類分配給基類變量與泛型

public interface IB<X, Y> 
    where X : class, IEntity 
    where Y : class, IEntity 
{ 
    ... 
} 

public abstract class A 
{ 
    ... 
} 

public abstract class B<X, Y> : A, IB<X, Y> 
    where X : class, IEntity 
    where Y : class, IEntity 
{ 
    ... 
} 

public interface IEntity 
{ 
    ... 
} 

public class Entity1 : IEntity 
{ 
    ... 
} 

public class Entity2 : IEntity 
{ 
    ... 
} 

public class C : B<Entity1, Entity2>, IB<Entity1, Entity2> 
{ 
    ... 
} 

,然後嘗試使用所有這一切在功能...

C c = new C(); 
IB<IEntity, IEntity> ib = c; 

無法implicityly或明確地施放此。

我該如何得到這個工作?

回答

3

您的界面不是共變有效的。也就是說,

IB<IEntity, IEntity>IB<Entity1, Entity2>不是一回事。爲了解決這個問題,你可以在接口定義

public interface IB<out X, out Y> where X : class where Y : class 

使用out關鍵字的類型參數作爲第二個點,你需要級聯的約束B類

public abstract class B<X, Y> : A, IB<X, Y> where X : class where Y : class 

有了這些變化,將你在C中的任務分配給ib是合法的。

C c = new C(); 
IB<IEntity, IEntity> ib = c; 

(正如Davy8正確的評論指出,該接口協方差特徵需要C#4+)

+2

也許總是要提一提,這需要C#4(和.NET 4.0?) – Davy8

+0

像魅力一樣工作!完善。謝謝謝謝! – smdrager

0

你需要改變的class B的定義如下:

public abstract class B<X, Y> : A, IB<X, Y> where X : class where Y : class 
{ 
    ... 
} 

約束在整個產業鏈中指定。