2013-09-21 173 views
3

我在實現父/子接口時遇到了問題,因爲它們都是通用接口。我能找到的最佳答案是,這是不可能的,但我也無法找到其他人詢問完全相同的問題。我希望我只是不知道正確的語法,以使編譯器明白我想要做什麼。這裏是我試圖實現的代碼的簡化示例。如何實現具有子通用接口的通用接口

public interface I_Group<T> 
    where T : I_Segment<I_Complex> 
{ 
    T Segment { get; set; } 
} 

public interface I_Segment<T> 
    where T : I_Complex 
{ 
    T Complex { get; set; } 
} 

public interface I_Complex 
{ 
    string SomeString { get; set; } 
} 

public partial class Group : I_Group<Segment> 
{ 
    private Segment segmentField; 

    public Group() { 
     this.segmentField = new Segment(); 
    } 

    public Segment Segment { 
     get { 
      return this.segmentField; 
     } 
     set { 
      this.segmentField = value; 
     } 
    } 
} 

public partial class Segment : I_Segment<Complex> { 

    private Complex complexField; 

    public Segment() { 
     this.complexField = new Complex(); 
    } 

    public Complex Complex { 
     get { 
      return this.c_C001Field; 
     } 
     set { 
      this.c_C001Field = value; 
     } 
    } 
} 

public partial class Complex : I_Complex { 

    private string someStringField; 

    public string SomeString { 
     get { 
      return this.someStringField; 
     } 
     set { 
      this.someStringField = value; 
     } 
    } 
} 

所以這裏Complex是孫子,它實現了I_Complex而沒有錯誤。 Segment是它的父類,它實現了I_Segment而沒有錯誤。問題在於祖父母Group試圖實施I_Group。我得到的錯誤

The type 'Segment' cannot be used as type parameter 'T' in the generic type or method 'I_Group<T>'. There is no implicit reference conversion from 'Segment' to 'I_Segment<I_Complex>'. 

導致我相信這是與協方差的問題,但我還帶領相信這東西,這應該是工作在C#4.0。當孩子不是通用的時候,這是有效的,這導致我認爲必須有一些語法才能正確編譯。難道我做錯了什麼?這甚至有可能嗎?如果沒有,有人可以幫我理解爲什麼不是?

+0

Segment的定義在哪裏? –

+0

它在那裏,你向下滾動? –

+0

* feelin stupid ... * –

回答

2

您可以添加第二個泛型類型參數爲I_Group接口聲明:

public interface I_Group<T, S> 
    where T : I_Segment<S> 
    where S : I_Complex 
{ 
    T Segment { get; set; } 
} 

,並明確指定Group類聲明兩種類型:

public partial class Group : I_Group<Segment, Complex> 

它會使你的代碼編譯。

+0

這正是我所期待的。經過一個小時的修改我的接口和類,它編譯沒有問題。非常感謝你! –

0

那麼,爲了使協變或逆變與界面一起工作,您可以使用「in」和「out」關鍵字。協方差使用了關鍵字,例如:

public interface A<out T> 
{ 
    T Foo(); 
} 

雖然逆變使用的關鍵字:

public interface B<in T> 
{ 
    Bar(T t); 
} 

你的情況的問題是,你的I_Segment接口不是協變或逆變,所以I_Segment不與I_Segment兼容,這就是爲什麼你得到一個編譯錯誤。