繁体   English   中英

可枚举派生类上的扩展方法无法推断类型 arguments

[英]Extension methods on enumerable-derived classes cannot infer type arguments

我们目前正在与 generics 合作开发可枚举派生类的扩展。 显然,如果在从IEnumerable<T>派生的 class 上调用扩展方法并返回包含T类型的值,则编译器会产生错误 CS0411 和扩展方法。

以下示例重现了该错误:

public class Item { }

public class CollectionType : IEnumerable<Item>
{
    public IEnumerator<Item> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

public static class CollectionExtension
{
    public static T[] DoSomething<T, TCollection>(this TCollection source)
        where TCollection : IEnumerable<T>
    {
        throw new NotImplementedException();
    }
}

public class Test
{
    public void TestMethod()
    {
        var collection = new CollectionType();

        collection.DoSomething();

        collection.DoSomething<Item, CollectionType>(); // This works fine
    }
}

调用DoSomething()将产生以下错误:

The type arguments for method 'T[] [...].CollectionExtension.DoSomething<T,TCollection>(this TCollection)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

如果TCollection被绑定为IEnumerable<T>类型并且T也被定义为DoSomething()的泛型类型参数,这怎么会发生?

CollectionType上调用扩展方法应该为DoSomething()提供两种泛型类型。

如果不明确指定泛型类型,就不可能按原样使用DoSomething()方法。 class IEnumerable<T>似乎可以从中推断出T的类型位于类型约束声明中,不幸的是 C# "...cannot infer the type parameters only from a constraint or return value" 在此处查看详细信息:

[https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generic-methods]

这个问题可以通过不同的方式解决,您可以像在示例代码中那样显式指定类型 - collection.DoSomething<Item, CollectionType>() ,或者向DoSomething()添加类型为T的参数,在这种情况下 C# 将能够推断类型,或摆脱泛型类型 TCollection,用IEnumerable<T>以下列方式替换它:

public static T[] DoSomething<T>(this IEnumerable<T> source)
{
    throw new NotImplementedException();
}

我认为最后一个会是一种更清洁的方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM