为什么不接受 IEnumerable(of T) 作为扩展方法接收器
本文关键字:扩展 方法 接收器 不接受 IEnumerable of 为什么 | 更新日期: 2023-09-27 18:32:28
在代码之前完成问题:
为什么不接受IEnumerable<T>
where T : ITest
作为期望this IEnumerable<ITest>
的扩展方法的接收方?
现在的代码:
我有三种类型:
public interface ITest { }
public class Element : ITest { }
public class ElementInfo : ITest { }
以及两种扩展方法:
public static class Extensions
{
public static IEnumerable<ElementInfo> Method<T>(
this IEnumerable<T> collection)
where T : ITest
{
→ return collection.ToInfoObjects();
}
public static IEnumerable<ElementInfo> ToInfoObjects(
this IEnumerable<ITest> collection)
{
return collection.Select(item => new ElementInfo());
}
}
我得到的编译器错误(在标记的行上):
CS1929
:'IEnumerable<T>'
不包含'ToInfoObjects'
的定义,最好的扩展方法重载'Extensions.ToInfoObjects(IEnumerable<ITest>)'
需要类型为'IEnumerable<ITest>'
的接收器
为什么会这样?ToInfoObjects
扩展方法的接收方是一个IEnumerable<T>
,并且通过泛型类型约束,T
必须实现ITest
。
那么为什么不接受接收器呢?我的猜测是IEnumerable<T>
的协方差,但我不确定。
如果我更改ToInfoObjects
以接收IEnumerable<T> where T : ITest
,那么一切都很好。
考虑一下:
public struct ValueElement : ITest { }
而这个:
IEnumerable<ValueElement> collection = ...
collection.Method(); //OK, ValueElement implement ITest, as required.
collection.ToInfoObjects() //Error, IEnumerable<ValueElement> is not IEnumerable<ITest>
//variance does not work with value types.
因此,并非每种类型都允许Method
也允许ToInfoObjects
.如果在 Method
中将约束添加到T
class
,则代码将编译。
您可以执行以下操作:
public static IEnumerable<ElementInfo> Method<T>(
this IEnumerable<T> collection)
where T : ITest
{
return collection.ToInfoObjects();
}
public static IEnumerable<ElementInfo> ToInfoObjects<T>(
this IEnumerable<T> collection)
{
return collection.Select(item => new ElementInfo());
}
关于ToInfoObjects的通知。