.NET:推断静态方法的泛型类型 [英] .NET: Inferred generic types on static methods

查看:126
本文介绍了.NET:推断静态方法的泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有

public static List<T2> Map<T,T2>(List<T> inputs, Func<T, T2> f)
{
    return inputs.ConvertAll((x) => f(x));
}

private int Square(int x) { return x*x; }

public void Run()
{
    var inputs = new List<Int32>(new int[]{2,4,8,16,32,64,128,256,512,1024,2048});

    // this does not compile
    var outputs = Map(inputs, Square); 

    // this is fine
    var outputs2 = Map<Int32,Int32>(inputs, Square);

    // this is also fine (thanks, Jason)
    var outputs2 = Map<Int32,Int32>(inputs, (x)=>x*x);

    // also fine
    var outputs2 = Map(inputs, (x)=>x*x);
}

为什么不编译?

编辑:错误是:


错误CS0411:无法从用法中推断出方法'Namespace.Map< T,T2>(System.Collections.Generic.List< T,System.Func< T,T2>))的类型参数。尝试显式指定类型参数。

error CS0411: The type arguments for method 'Namespace.Map<T,T2>(System.Collections.Generic.List<T>, System.Func<T,T2>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

为什么必须指定Map()函数的类型?它不能从传递的 Func< T> 推断出来吗? (在我的情况下为Square)

Why do I have to specify the type of the Map() function? Can it not infer this from the passed Func<T> ? (in my case, Square)

答案与

C#3.0泛型类型推断-传递委托作为函数参数

推荐答案

从您的错误消息中:


方法' [...]。Map< T,T2>(System.Collections.Generic.List< T> ;, System.Func< ; T,T2>)'不能从用法中推断出来。尝试显式指定类型参数。

The type arguments for method '[...].Map<T,T2>(System.Collections.Generic.List<T>, System.Func<T,T2>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

请注意,错误消息指出无法确定类型参数。也就是说,它无法解析类型参数 T T2 之一。这是因为规范的第25.6.4节(类型参数的推断)。这是规范中涉及推断泛型类型参数的部分。

Note that the error message says that it can not figure out the type arguments. That is, it is having trouble resolving one of the type parameters T or T2. This is because of §25.6.4 (Inference of type arguments) of the specification. This is the part of the specification the deals with inferring generic type parameters.


如果没有从参数中推断出任何内容(但类型推断成功),如果满足以下任何条件:

Nothing is inferred from the argument (but type inference succeeds) if any of the following are true:

[...]

该参数是方法组。

因此,编译器无法使用 Square 的委托类型来推断 T2 的类型。请注意,如果将声明更改为

Thus, the compiler is not able to use the delegate type of Square to infer the type of T2. Note that if you change the declaration to

public static List<T> Map<T>(List<T> inputs, Func<T, T> f) {
        return inputs.ConvertAll((x) => f(x));
}

然后

var outputs = Map(inputs, Square);

是合法的。在这种情况下,它已经根据 inputs <<来解决 T int 的问题。 / code>是 List< int>

is legal. In this case, it has already resolved that T is int from the fact that inputs is a List<int>.

现在,更深层的问题是为什么高于规格?也就是说,为什么方法组在类型参数解析中不起作用?我认为是因为这样的情况:

Now, the deeper question is why is the above the specification? That is, why don't method groups play a role in type parameter resolution? I think it's because of cases like this:

class Program {
    public static T M<T>(Func<T, T> f) {
        return default(T);
    }

    public static int F(int i) {
        return i;
    }

    public static float F(float f) {
        return f;
    }

    static void Main(string[] args) {
        M(F); // which F am I?
    }
}

这篇关于.NET:推断静态方法的泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆