为什么不能't方法返回List<实现一个返回IEnumerable的方法

本文关键字:返回 方法 一个 IEnumerable 不能 List 实现 为什么 | 更新日期: 2023-09-27 18:08:45

我有一个实现带有方法签名的接口的具体类

IEnumerable<T> Foo()

List<T> Foo()

编译器说List<T> Foo不能实现IEnumerable<T> Foo。为什么?

为什么不能't方法返回List<实现一个返回IEnumerable<T>的方法

为什么编译器拒绝这个?

因为规范不允许这样做:

对于接口映射,类成员a在下列情况下匹配接口成员B:

  • A和B为方法,A和B的名称、类型和形式参数表相同。

  • […]

(引自c# 5.0规范- 13.4.4接口映射)

如果要将此功能添加到规范中,是否存在任何技术障碍?

Not that I know of:

  • 由于这两种类型都是引用类型,它们是保留表示的。因此,这些签名之间存在二进制兼容性。
  • 返回类型的协方差是类型安全的,因为返回List<T>的方法返回接口
  • 调用者期望的IEnumerable<T>

c#和。net中已经有类似的特性了吗?

. net 4支持:
  • 委托返回类型的协方差:Func<List<T>>Func<IEnumerable<T>>
  • 接口协方差:IEnumerable<List<T>>IEnumerable<IEnumerable<T>

这进一步证明了该特性的可行性。

为什么不支持呢?

只有c#团队的成员才能明确地回答这个问题。

但在缺乏进一步证据的情况下,我们可以假设:

每个特性都有指定、实现、测试和维护的成本。因此,开发人员只能实现一些功能。他们会选择那些花费很少就能获得巨大收益的功能。所以可能有更高优先级的功能,不值得他们花时间。

有解决方法吗?

直接使用显式接口实现:

class FooClass<T> : IFoo
{
    public List<T> Foo()
    {
         //do something
    }
    IEnumerable<T> IFoo.Foo()
    {
        return Foo();
    }
}

因为你不能改变你在c#中实现的方法的返回类型或任何其他类型

c#的语言规范是这么说的。他们为什么做出这个决定是未知的,但作为一个大胆的猜测,他们可能认为潜在的收益不值得付出代价。

您可以做的是保留签名为IEnumerable<T>,并简单返回List<T>

我不能回答为什么这个问题,但值得注意的是,这个限制几乎没有实际影响,因为显式接口实现允许您使用少量粘合代码获得所需的效果:

public interface IFooable<T>
{
    IEnumerable<T> Foo();
}
public sealed class Fooable<T> : IFooable<T>
{
    public List<T> Foo()
    {
        //...
    }
    IEnumerable<T> IFooable<T>.Foo()
    {
        return Foo();
    }
}