如何实现具有子通用接口的通用接口

问题描述:

我在实现父/子接口时遇到了问题,因为它们都是通用接口。我能找到的最佳答案是,这是不可能的,但我也无法找到其他人询问完全相同的问题。我希望我只是不知道正确的语法,以使编译器明白我想要做什么。这里是我试图实现的代码的简化示例。如何实现具有子通用接口的通用接口

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 ... * –

您可以添加第二个泛型类型参数为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

这正是我所期待的。经过一个小时的修改我的接口和类,它编译没有问题。非常感谢你! –

那么,为了使协变或逆变与界面一起工作,您可以使用“in”和“out”关键字。协方差使用了关键字,例如:

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

虽然逆变使用的关键字:

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

你的情况的问题是,你的I_Segment接口不是协变或逆变,所以I_Segment不与I_Segment兼容,这就是为什么你得到一个编译错误。