【发布时间】:2009-09-02 11:14:29
【问题描述】:
delegate void DelegateTest();
DelegateTest delTest;
调用delTest.Invoke() 和delTest() 有什么区别?两者都会在当前线程上执行委托,对吧?
【问题讨论】:
delegate void DelegateTest();
DelegateTest delTest;
调用delTest.Invoke() 和delTest() 有什么区别?两者都会在当前线程上执行委托,对吧?
【问题讨论】:
delTest() 表单是一个编译器助手,在它下面实际上是对Invoke() 的调用。
【讨论】:
obbject[] 传递参数并返回object。
Richard 的回答是正确的,但是从 C# 6.0 开始,由于添加了 null conditional operator,在一种情况下直接使用 Invoke() 可能是有利的。根据 MS 文档:
空条件成员访问的另一个用途是以线程安全的方式调用委托,代码少得多。旧方式需要如下代码:
var handler = this.PropertyChanged; if (handler != null) handler(…);新方法要简单得多:
PropertyChanged?.Invoke(…)新方法是线程安全的,因为编译器生成的代码只计算一次 PropertyChanged,将结果保存在一个临时变量中。您需要显式调用 Invoke 方法,因为没有空条件委托调用语法 PropertyChanged?(e)。
【讨论】:
没错。两者的结果完全相同。
当然,鉴于您已正确初始化 delTest。
【讨论】:
delTest 是 null,这两种语法再次导致相同的结果(在这种情况下,NullReferenceException 从尝试调用的行抛出)。
Delegate.Invoke 和 Delegate() 是相同的。两者都做同样的事情 .见下面代码
static async Task Main(string[] args)
{
MyDelegate mydelegate = new MyDelegate(CallMe);
mydelegate.Invoke("Reza");
mydelegate("Reza");
}
public delegate void MyDelegate(string message);
public static void CallMe(string message)
{
}
IL
IL_001a: ldarg.0
IL_001b: ldfld class TestConsole.Program/MyDelegate TestConsole.Program/'<Main>d__1'::'<mydelegate>5__1'
IL_0020: ldstr "Reza"
IL_0025: callvirt instance void TestConsole.Program/MyDelegate::Invoke(string)
IL_002a: nop
IL_002b: ldarg.0
IL_002c: ldfld class TestConsole.Program/MyDelegate TestConsole.Program/'<Main>d__1'::'<mydelegate>5__1'
IL_0031: ldstr "Reza"
IL_0036: callvirt instance void TestConsole.Program/MyDelegate::Invoke(string)
IL_003b: nop
我通常使用Invoke(),因为您可以使用 null-check,并且阅读代码的人可以更轻松地看到正在使用委托。
空检查
MyDelegate mydelegate = null;
mydelegate?.Invoke("Reza");
mydelegate("Reza"); // Error: System.NullReferenceException
【讨论】: