Roy*_*mir 2 .net c# generics .net-4.0
我在这里读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...");
}
Run Code Online (Sandbox Code Playgroud)
但是如何Foo(Func<int, int>)处理delegate { return x; }哪个是Func<int>?
事实上也Func< int,int,int,int,...>可以处理delegate { return x; }......
问题1 对此行为有任何解释吗?
问题2
我有这个代码:
class MyClass
{
public delegate void MyEventHandler(object sender);
public event MyEventHandler MyEvent;
}
Run Code Online (Sandbox Code Playgroud)
我想使用通用处理程序,所以:
class MyClass
{
public Action<object> MyEventHandler;
public event MyEventHandler MyEvent;
}
Run Code Online (Sandbox Code Playgroud)
但我得到这个错误:
'UserQuery.MyClass.MyEventHandler(object)'是'方法',但用作'类型'
为什么不承认呢?
第一个问题的答案是代理的参数是由编译器推断的.编译一个匿名方法,该方法将一个int参数作为参数,并且根本不做任何操作.代码可能是这样编写的:
Foo( delegate (int dummy) { return x; } );
Run Code Online (Sandbox Code Playgroud)
通过省略参数列表,您告诉编译器发出一个方法,该方法与当前上下文中的委托类型具有相同的参数类型.编译器知道a Func<int, int>是预期的,因此它能够使匿名方法的参数类型匹配.
换句话说,delegate { ... }告诉编译器"创建一个匿名方法,但我不关心参数是什么,因为我不会使用它们,所以发出任何参数将允许此委托在此上下文中被接受." (这与delegate () { ... }"创建一个带零参数的匿名方法" 不同.请注意括号.如果将这些括号添加到示例代码中,它确实无法编译.)
在第二种情况下,您使用的是字段名称,其中包含类型名称.定义字段不会创建具有字段名称的类型.你的第一个例子是正确的; 在这种情况下,MyEventHandler是一个类型,而不是一个字段.(即使它确实有效,使用泛型也不会有用,因为最终的委托签名已在编译时确定.使用泛型不会带来任何净优势.)
| 归档时间: |
|
| 查看次数: |
306 次 |
| 最近记录: |