谜我:为什么会发生隐式接口实现错误?

Kee*_*ker 3 .net c# generics interface abstract

请考虑以下代码行:

public interface IProduct
{
    string Name { get; set; }
}

public interface IProductList
{
    string Name { get; }

    IProduct GetValueObject();
}

public abstract class BaseProductList<T> : IProductList where T : class, IProduct, new()
{
    public abstract T GetValueObject();

    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这给了我以下警告: 错误1 ConsoleApplication1.EnumTest.BaseProductList-T-未实现接口成员ConsoleApplication1.EnumTest.IProductList.GetValueObject(). ConsoleApplication1.EnumTest.BaseProductList-T-.GetValueObject()无法实现ConsoleApplication1.EnumTest.IProductList.GetValueObject(),因为它没有匹配的返回类型ConsoleApplication1.EnumTest.IProduct

(错误1'ConsoleApplication1.EnumTest.BaseProductList'没有实现接口成员'ConsoleApplication1.EnumTest.IProductList.GetValueObject()'.'ConsoleApplication1.EnumTest.BaseProductList.GetValueObject()'无法实现'ConsoleApplication1.EnumTest.IProductList.GetValueObject() '因为它没有匹配的返回类型'ConsoleApplication1.EnumTest.IProduct'.\ cencibel\homes $\k.bakker\visual studio 2010\Projects\ConsoleApplication1\ConsoleApplication1\EnumTest\Program.cs 29 23 TestApp)

但是,当我添加这段明确的代码时,它可以工作:

IProduct IProductList.GetValueObject()
{
    return GetValueObject();
}
Run Code Online (Sandbox Code Playgroud)

为什么.Net无法想出这个!?

Jon*_*eet 7

返回的方法IProduct一样返回一些型implementing-的方法IProduct.您正在尝试使用协变返回类型 - 这是.NET不支持的.

基本上它与这种情况类似:

// Doesn't compile
class Foo : ICloneable
{
    public Foo Clone()
    {
        return new Foo();
    }
}
Run Code Online (Sandbox Code Playgroud)

看起来很好,并允许客户端调用Clone()并获取强类型值 - 但它不实现接口.这在.NET中是不受支持的,而且从来没有 - 您的代码中的泛型只是同一问题的另一个例子.

  • @ KeesC.Bakker:人们要求我们提供此功能 - 覆盖虚拟返回类型的协方差 - 始终如一.(奇怪的是,没有人要求参数类型的*逆变*.)我们不会这样做,对不起.它不受运行时支持,它引入了脆弱基类失败的新形式,并且我们有更重要的特性可供使用.我不讨厌这个功能 - 如果我拥有它,我会使用它 - 但多年来我一直参加许多语言设计会议,我们决定不这样做,所以它不太可能达到重要功能列表的顶部. (3认同)