为什么不接受 IEnumerable(of T) 作为扩展方法接收器
Why is IEnumerable(of T) not accepted as extension method receiver
在代码前完成问题:
为什么 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>'
does not contain a definition for 'ToInfoObjects'
and the best extension method overload 'Extensions.ToInfoObjects(IEnumerable<ITest>)'
requires a receiver of type 'IEnumerable<ITest>'
为什么会这样? ToInfoObjects
扩展方法的接收者是一个 IEnumerable<T>
,根据泛型类型约束,T
必须实现 ITest
。
为什么收件人不接受?我的猜测是 IEnumerable<T>
的协方差,但我不确定。
如果我把ToInfoObjects
改成接收IEnumerable<T> where T : ITest
,那就没问题了
您可以执行以下操作:
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 的通知。
考虑一下:
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
。如果您将 class
约束添加到 Method
中的 T
,那么您的代码将通过编译。
在代码前完成问题:
为什么 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>'
does not contain a definition for'ToInfoObjects'
and the best extension method overload'Extensions.ToInfoObjects(IEnumerable<ITest>)'
requires a receiver of type'IEnumerable<ITest>'
为什么会这样? ToInfoObjects
扩展方法的接收者是一个 IEnumerable<T>
,根据泛型类型约束,T
必须实现 ITest
。
为什么收件人不接受?我的猜测是 IEnumerable<T>
的协方差,但我不确定。
如果我把ToInfoObjects
改成接收IEnumerable<T> where T : ITest
,那就没问题了
您可以执行以下操作:
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 的通知。
考虑一下:
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
。如果您将 class
约束添加到 Method
中的 T
,那么您的代码将通过编译。