为什么不接受 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,那么您的代码将通过编译。