2013-10-22 84 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

這就是爲什麼這不檢查類型。