为什么不能't方法返回List<实现一个返回IEnumerable的方法
本文关键字:返回 方法 一个 IEnumerable 不能 List 实现 为什么 | 更新日期: 2023-09-27 18:08:45
我有一个实现带有方法签名的接口的具体类
IEnumerable<T> Foo()
List<T> Foo()
编译器说List<T> Foo
不能实现IEnumerable<T> Foo
。为什么?
为什么编译器拒绝这个?
因为规范不允许这样做:
对于接口映射,类成员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();
}
}