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

时间:2014-02-13 14:51:51

标签: 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);
    }
}

如果我更改参数以接受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);
    }
}

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

2 个答案:

答案 0 :(得分:8)

DoStuff<T>方法中,T的实际类型未知;您的代码会将int传递给函数,假设Tint,但T实际上可以是任何内容,例如string,所以您将通过int到仅接受string s。

的函数

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

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

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

  • 在C#中,没有基于用法的编译时生成;编译器只生成1个泛型方法,并且运行时生成给定T的实际运行时方法。为了确保这一点,C#编译器必须确保方法体对任何T都有效(或者如果您为T指定了约束,那么任何T都符合约束条件。这就是为什么你的第一个片段出现错误的原因:只有当Tint时,泛型方法的正文才有效。

我建议你阅读this question的答案,以获得更详细的解释。

答案 1 :(得分:1)

这里不需要使用泛型。变化

static void DoStuff<T>(Func<T, T, T> fn)

static void DoStuff(Func<int, int, int> fn)
相关问题