C# 如何使用子泛型接口实现泛型接口

C# 如何使用子泛型接口实现泛型接口,c#,c#-4.0,generics,interface,C#,C# 4.0,Generics,Interface,我在实现父/子接口时遇到了一个问题,因为它们都是泛型的。我能找到的最好的答案是这是不可能的,但我也找不到其他人提出完全相同的问题。我希望我只是不知道正确的语法,让编译器理解我要做的事情。下面是我试图实现的代码的一个精简示例 public interface I_Group<T> where T : I_Segment<I_Complex> { T Segment { get; set; } } public interface I_Segment<

我在实现父/子接口时遇到了一个问题,因为它们都是泛型的。我能找到的最好的答案是这是不可能的,但我也找不到其他人提出完全相同的问题。我希望我只是不知道正确的语法,让编译器理解我要做的事情。下面是我试图实现的代码的一个精简示例

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;
        }
    }
}
公共接口I\u组
其中T:I_段
{
T段{get;set;}
}
公共接口I_段
T:I_复合体在哪里
{
T复数{get;set;}
}
公共界面综合设施
{
字符串SomeString{get;set;}
}
公共部分类组:I_组
{   
私有段段段字段;
公共组(){
this.segmentField=新段();
}
公共部分{
得到{
返回此字段;
}
设置{
this.segmentField=值;
}
}
}
公共部分类段:I_段{
私人综合体;
公共部分(){
this.complexField=new Complex();
}
公共综合体{
得到{
返回此.c_C001字段;
}
设置{
此.c_C001字段=值;
}
}
}
公共部分类复合体:I_复合体{
私有字符串字段;
公共字符串SomeString{
得到{
返回此.someStringField;
}
设置{
this.someStringField=值;
}
}
}
这里,Complex是孙子,它实现了I_Complex,没有错误。段是它的父段,它实现I_段而没有错误。问题在于祖父母团队,试图实施I_团队。我得到了错误

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>'.
类型“段”不能用作泛型类型或方法“I_组”中的类型参数“T”。没有从“段”到“I_段”的隐式引用转换。

我被引导相信这是一个协方差的问题,但我也被引导相信这在C#4.0中应该起作用。当子类不是泛型的时候,这就起作用了,这让我认为必须存在一些语法才能正确编译它。我做错什么了吗?这可能吗?如果没有,有人能帮我理解为什么没有吗?

您可以将第二个泛型类型参数添加到
I\u组
接口声明中:

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

它将使您的代码得以编译。

好吧,要获得协方差或协方差来处理接口,您可以使用“in”和“out”关键字。协方差使用out关键字,例如:

public interface A<out T>
{
    T Foo();
}
公共接口A
{
T Foo();
}
而逆变使用in关键字:

public interface B<in T>
{
    Bar( T t );
}
公共接口B
{
巴(T);
}

本例中的问题是I_段接口不是协变或逆变的,因此I_段与I_段不兼容,这就是为什么会出现编译错误

你对段的定义在哪里?在那里,你向下滚动了吗?如果你像这样写段:
public partial class段:I_段
请不要在
I
和名称之间写下划线,这是一种糟糕的编程风格。@Chiel92虽然这样编译,它要求将成员更改为接口类型,而不是显式类类型。这最终破坏了我为使用这些类而编写的代码。这正是我想要的。在修改我的接口和类一个小时后,它编译成功了。非常感谢你!