c# - 隐式和显式委托(delegate)创建之间的区别(有和没有泛型)

标签 c# .net generics .net-2.0 delegates

请参阅下面 Go() 方法中的四行:

delegate void Action<T>(T arg);
delegate void Action();

void DoSomething<T>(Action<T> action)
{
    //...
}

void DoSomething(Action action)
{
    //...
}

void MyAction<T>(T arg)
{
    //...
}

void MyAction()
{
    //...
}

void Go<T>()
{
    DoSomething<T>(MyAction<T>); // throws compiler error - why?
    DoSomething(new Action<T>(MyAction<T>)); // no problems here
    DoSomething(MyAction); // what's the difference between this...
    DoSomething(new Action(MyAction)); // ... and this?
}

注意第一次调用产生的编译器错误是: 无法从用法中推断出方法“Action(T)”的类型参数。尝试明确指定类型参数。

最佳答案

MyActionnew Action(MyAction) 之间没有区别(当它们都有效时),只是前者在 C# 1 中不起作用。这是隐式方法组转换。有时这是不适用的,最值得注意的是当编译器无法计算出您想要哪种委托(delegate)时,例如

Delegate foo = new Action(MyAction); // Fine
Delegate bar = MyAction; // Nope, can't tell target type

这在您的问题中发挥了作用,因为所涉及的两种方法都已重载。这基本上会导致头痛。

至于泛型方面 - 这很有趣。方法组并没有从 C# 3 类型推断中得到太多的爱——我不确定这是否会在 C# 4 中得到改进。如果您调用泛型方法并指定类型参数,类型推断工作得很好 - 但如果您尝试以相反的方式进行,它会失败:

using System;

class Test
{
    static void Main()
    {
        // Valid - it infers Foo<int>
        DoSomething<int>(Foo);
        // Valid - both are specified
        DoSomething<int>(Foo<int>);
        // Invalid - type inference fails
        DoSomething(Foo<int>);
        // Invalid - mismatched types, basically
        DoSomething<int>(Foo<string>);
    }

    static void Foo<T>(T input)
    {
    }

    static void DoSomething<T>(Action<T> action)
    {
        Console.WriteLine(typeof(T));
    }
}

C# 3 中的类型推断非常复杂,并且在大多数情况下运行良好(特别是对于 LINQ 非常有用)但在其他一些情况下会失败。在理想情况下,它会变得更容易理解并且在未来的版本中会更强大......我们拭目以待!

关于c# - 隐式和显式委托(delegate)创建之间的区别(有和没有泛型),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/863688/

相关文章:

c# - 将 C# 连接到 SQL Server Compact 数据库

c# - UseIIS 值的不可预测的变化(VS2015)

c# - c# .net Compact Framework 3.5 中最快的字典查找

c# - 为什么 "dynamic"在用作泛型类型参数时对于所有类型都不是协变和逆变的?

java - 从对象中检索类名/实例

Java:泛型参数上带有.class的泛型方法

c - 是否可以使用 C11 的 _Generic 实现 GNU C 的 typeof(x)?

c# - Entity Framework 6 - Group by then Order by the First() 花费的时间太长

c# - Resharper:如何使用括号作为大括号和缩进参数来格式化多行方法?

c# - C# 4.0 中的命名参数和泛型类型推断