C#Func <>委托参数转换错误

Pow*_*101 2 c# lambda delegates

当我运行这个程序时,我在包含fn(3,4)的行上得到两个错误

参数1:无法从'int'转换为T.

参数2:无法从'int'转换为T.

我认为类型T将是int,由lambda指定.但如果是这样,为什么转换错误呢?我误会了什么吗?

class Program
{
    static void DoStuff<T>(Func<T, T, T> fn)
    {
        Console.WriteLine(fn(3, 4));
    }

    static void Main()
    {
        DoStuff((int x, int y) => x + y);
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我更改参数以接受int作为参数,这是有效的:

class Program
{
    static void DoStuff<T>(T x, T y, Func<T, T, T> fn)
    {
        Console.WriteLine(fn(x, y));
    }

    static void Main()
    {
        DoStuff(3, 4, (int x, int y) => x + y);
    }
}
Run Code Online (Sandbox Code Playgroud)

我来自C++背景,因此试图了解C#中哪些有效,哪些无效

Tho*_*que 8

DoStuff<T>方法内部,实际类型T是未知的; 你的代码传递int给函数,假设Tint,但T实际上可能是任何东西string,所以你将ints 传递给只接受strings 的函数.


RE"我来自C++背景,因此试图了解C#中的有效和无效的内容":

C#泛型看起来与C++模板类似,但它们实际上是完全不同的.

  • 在C++中,模板在编译时根据使用情况进行实例化; 如果对T使用3种不同类型的模板方法,编译器将生成3种不同的方法.模板方法的主体不必对任何有效T,只要它对实际使用情况有效.(对不起,如果我的解释不完全准确;我不太了解C++)

  • 在C#中,没有基于用法的编译时生成; 编译器只生成1个泛型方法,并且给定的实际运行时方法T由运行时生成.为了确保这一点可行,C#编译器必须确保方法体对任何T(或者如果您指定的约束T,T对于与约束匹配的任何约束)都有效.这就是为什么你在你的第一个片段得到一个错误:通用方法的主体只能是有效的,如果Tint.

我建议你阅读这个问题的答案,以获得更详细的解释.