Delegate.Invoke和Delegate()的区别

49
delegate void DelegateTest();

DelegateTest delTest;

调用delTest.Invoke()delTest()有什么区别?两者都会在当前线程上执行委托,对吗?

4个回答

60

delTest() 表单是编译器助手,其实它是对 Invoke() 的调用。


3
@Richard:Invoke()在内部执行了什么操作?这个Invoke方法确切地位于哪里?我在Delegate和MultiCastDelegate的元数据文件中都没有找到。 - Novice
3
@Jose:它们是CLR内部实现的一部分,很可能被JIT编译器直接理解。 - Richard
@Richard:感谢您的回复。后来我在SO上看到了一个类似的问题。还有一个问题,委托的DynamicInvoke是什么意思?我在一些论坛上读到过关于late-bound的讨论,但我不理解它的用法。 - Novice
@Jose:当使用反射动态执行方法时,它是MethodInfo.Invoke的委托等效项:将参数作为object[]传递并返回object - Richard
我的老教授会把这称为“语法糖”。 - Drazen Bjelovuk

23

Richard的回答是正确的,不过从C# 6.0开始,使用Invoke()直接调用可以在使用空值条件运算符时具有优势。根据微软文档:

另一个使用空值条件成员访问的情况是通过更少的代码以线程安全的方式调用委托。旧的方法需要如下所示的代码:

var handler = this.PropertyChanged;
if (handler != null)  
    handler(…);

新方式更简单:

PropertyChanged?.Invoke(…)   

新的方式是线程安全的,因为编译器生成的代码只评估了一次PropertyChanged并将结果保存在临时变量中。您需要显式调用Invoke方法,因为没有空引用委托调用语法PropertyChanged?(e)。


3

没错,两者的结果完全相同。

当然,前提是您已经正确初始化了delTest


1
如果delTestnull,两种语法再次导致相同的结果(在那种情况下是从尝试调用的行抛出一个NullReferenceException)。 - Jeppe Stig Nielsen

3

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并且阅读代码的人更容易看出正在使用委托。

null-check

MyDelegate mydelegate = null;
mydelegate?.Invoke("Reza");
mydelegate("Reza"); // Error: System.NullReferenceException

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接