代替接口失败的类

时间:2013-09-11 20:57:51

标签: c# .net interface

interface I1
{
}
class ClassOfI1 : I1
{
}

interface I2
{
    I1 ABC { get; set; }
}
class ClassOfI2 : I2
{
    public ClassOfI1 ABC { get; set; }
}

引发以下错误:

  

'ns.ClassOfI2'没有实现接口成员'ns.I2.ABC'。   'ns.ClassOfI2.ABC'无法实现'ns.I2.ABC',因为它没有   具有匹配的返回类型'ns.I1'。

为什么呢? (有没有办法解决这个问题?我想要ClassOfI1,而不仅仅是界面。)

4 个答案:

答案 0 :(得分:4)

实现接口时,返回类型必须完全匹配。 C#不支持返回类型协方差。因此,您的实施应该是:

class ClassOfI2 : I2
{
    public I1 ABC { get; set; }
}

即使它确实如此,您的代码仍然不安全,因为您可以这样做:

public class Other : I1 { ... }
I2 iface = new ClassOfI2();
iface.ABC = new Other();

您可以考虑使用泛型:

interface I2<T> where T : I1
{
    T ABC { get; set; }
}

class ClassOfI2 : I2<ClassOfI1>
{
    public ClassOfI1 ABC { get; set; }
}

答案 1 :(得分:1)

因为你的方法返回ClassOfI1而不是I1!它应该返回接口本身。稍后您可以返回一个具体的类(在本例中为ClassOfI1),但实现中的定义必须与接口中的定义相匹配! 所以将代码更改为:

interface I1
{
}

class ClassOfI1 : I1
{
}

interface I2
{
    I1 ABC { get; set; }
}

class ClassOfI2 : I2
{
    public I1 ABC { get; set; }
}

它应该有用。

您可以在代码中稍后使用ClassOfI1的实例,例如:

var c1 = new ClassOfI1();
var c2 = new ClassOfI2();
c2.ABC = c1;

答案 2 :(得分:0)

这是一种方法:

class ClassOfI2 : I2
{
    ClassOfI1 _ABC;
    public I1 ABC { get { return _ABC; } set { _ABC = (ClassOfI1)value; } }
}

请注意,这将在Lee的回答中引发一个例外情况,但是当仅与ClassOfI1一起使用时 - 它运行正常。

答案 3 :(得分:0)

我刚看到this answer,这似乎是正确的方法:通用接口

缺点:

制作ABC的类型(I2): T where T: I1