【问题标题】:How to implement a generic interface with a child generic interface如何使用子泛型接口实现泛型接口
【发布时间】:2013-09-21 21:07:55
【问题描述】:

当它们都是通用的时,我在实现父/子接口时遇到问题。我能找到的最佳答案是不可能,但我也找不到其他人问完全相同的问题。我希望我只是不知道正确的语法来让编译器理解我想要做什么。这是我尝试实现的代码的精简示例。

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 没有错误。问题在于试图实现 I_Group 的祖父母 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 中工作的东西。当孩子不是通用的时,这有效,这使我认为必须存在一些语法才能使其正确编译。难道我做错了什么?这甚至可能吗?如果没有,有人可以帮我理解为什么不?

【问题讨论】:

  • 您对 Segment 的定义在哪里?
  • 它在那里,你向下滚动了吗?
  • 如果你这样写段会发生什么:public partial class Segment : I_Segment&lt;I_Complex&gt;
  • 请不要在I 和名称之间写下划线,这是一种糟糕的编程风格。
  • @Chiel92 虽然这确实可以编译,但它要求将成员更改为接口类型,而不是显式的类类型。这最终破坏了我已经编写的使用这些类的代码。

标签: c# c#-4.0 generics interface


【解决方案1】:

您可以在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>

它会让你的代码编译。

【讨论】:

  • 这正是我想要的。经过一个小时修改我的接口和类后,它编译没有问题。非常感谢!
【解决方案2】:

好吧,要让协变或逆变与接口一起工作,您可以使用“in”和“out”关键字。协方差使用 out 关键字,例如:

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

而逆变使用 in 关键字:

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

您的问题是您的 I_Segment 接口不是协变或逆变的,因此 I_Segment 与 I_Segment 不兼容,这就是您收到编译错误的原因。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多