2013-10-22 48 views
-1

我有以下接口:接口与接口类型的通用对象

public interface IObject 
{ 
    double x { get; } 
    double y { get; } 
    Holder<IObject> Holder { get; set; } 
} 

和这个类

public class Holder<T> where T : IObject 
{ 
    private List<T> items; 
    public void AddItem(T item){ 
    items.Add(item); 
    item.Holder = this; 
} 

但是编译器不喜欢该线路上AddItem方法和:

item.Holder = this; 

给我这个错误:

Cannot convert source type 'Holder<T>' to target type 'Holder<IObject>' 

为什么我不能做到这一点,什么是这种情况下的一个很好的解决方案? 谢谢

+1

为什么不使用公共类持有人

解释理论中的方案有天然化,这里是一个例子后? –

+3

你为什么两次问同样的问题? –

+0

这不是同一个问题,我在前面的问题上犯了太多错误,所以我写了一个新问题。这也是一个不同的例子。 – amramaz

回答

1

你必须记住Genrics在C#中的工作方式,编译器会创建一个指定类型的类,并且因此你有错误。

为了解释更多,因为下面的例子:

public class InterfaceImplementation : IObject 
{ 
} 

,然后一些,你这样做:

var genericInitialisation = new Holder<InterfaceImplementation>(); 

在编译时,编译器会创建一个类HolderInterfaceImplementation更换T的所有accurances泛型参数。

所以编译后,你将拥有这个类:

public class HolderInterfaceImplementation 
{ 
    private ListInterfaceImplementation items; 
    public void AddItem(InterfaceImplementation item){ 
    items.Add(item); 
    item.Holder = this; 
} 

而且item.HolderHolderIObject类型,所以编译器报告有关无法转换HolderInterfaceImplementationHolderIObject至极的逻辑错误。

public interface IObject<T> where T : IObject<T> 
    { 
     double x { get; } 
     double y { get; } 
     Holder<T> Holder { get; set; } 
    } 


    public class Holder<T> where T : IObject<T> 
    { 
     public Holder() 
     { 
     items = new List<T>(); 
     } 
     private List<T> items; 
     public void AddItem(T item) 
     { 
     items.Add(item); 
     item.Holder = this; 
     } 
    } 

    public class Implementation : IObject<Implementation> 
    { 

     public double x 
     { 
     get { return 0; } 
     } 

     public double y 
     { 
     get { return 0; } 
     } 

     public Holder<Implementation> Holder 
     { 
     get; 
     set; 
     } 
    } 
    static void Main(string[] args) 
    { 
     var t = new Holder<Implementation>(); 
     t.AddItem(new Implementation()); 
     Console.ReadKey(); 
    } 
+0

真棒和详细的答案,谢谢。 – amramaz

1

如果可以转换,这将是一个类型的系统漏洞:

public class Holder<T> where T : IObject 
{ 
    public T SomeField; 
} 
... 
var holder = new Holder<IObjectSubType2>(); 
Holder<IObject> dummy = holder; //assuming that this works 
dummy.SomeField = new IObjectSubType1(); //violates type safety 
IObjectSubType2 converted = holder.SomeField; 

正如你看到的我是能够的IObjectSubType1实例转换为IObjectSubType2

这就是为什么这不检查类型。