2

我在这里阅读 Jon Skeet 的回答

他的样本之一是:

  static void Main()
    {
        int x = 0;
        Foo( delegate { return x; } );
    }

    static void Foo(Func<int, int> action)
    {
        Console.WriteLine("I suspect the anonymous method...");
    }

但是怎么Foo(Func<int, int>)处理delegate { return x; }which isFunc<int>呢?

事实上也Func< int,int,int,int,...>可以处理delegate { return x; }...

问题 1 请对此行为有任何解释吗?

问题2

我有这个代码:

class MyClass
{
    public delegate void MyEventHandler(object sender);
    public  event MyEventHandler MyEvent;
}

我想使用通用处理程序:

class MyClass
{
    public  Action<object> MyEventHandler;
    public  event MyEventHandler MyEvent;
}

但我收到此错误:

'UserQuery.MyClass.MyEventHandler(object)' 是一个“方法”,但用作“类型”

为什么它不认识它?

4

1 回答 1

8

您的第一个问题的答案是委托的参数是由编译器推断的。编译了一个匿名方法,它接受一个int作为参数,并且什么都不做。代码可以这样写:

Foo( delegate (int dummy) { return x; } );

通过省略参数列表,您是在告诉编译器发出一个与当前上下文中的委托类型具有相同参数类型的方法。编译器知道 aFunc<int, int>是预期的,因此它能够使匿名方法的参数类型匹配。

换句话说,delegate { ... }告诉编译器“创建一个匿名方法,但我不关心参数是什么,因为我不会使用它们,所以发出任何参数将允许这个委托在这种情况下是可接受的。” (这与delegate () { ... }“创建一个接受零参数的匿名方法”不同。注意括号。如果将这些括号添加到示例代码中,它确实会编译失败。)

在第二种情况下,您正在使用需要类型名称的字段名称。定义字段不会创建具有字段名称的类型。你的第一个例子是正确的;在这种情况下,MyEventHandler是一个类型而不是一个字段。(即使这确实有效,使用泛型也不会真正有帮助,因为最终的委托签名已经在编译时确定。使用泛型不会获得任何净优势。)

于 2012-11-10T20:54:27.703 回答