delegate void DelegateTest();
DelegateTest delTest;
调用delTest.Invoke()
和delTest()
之间的区别是什么?两者都会在当前线程上执行委托,对吗?
答案 0 :(得分:39)
delTest()
表单是一个编译器助手,在它下面实际上是对Invoke()
的调用。
答案 1 :(得分:4)
理查德的答案是正确的,但是从C#6.0开始,有一种情况是由于添加了null conditional operator,直接使用Invoke()
可能是有利的。根据MS文档 -
空条件成员访问的另一个用途是以线程安全的方式使用更少的代码调用委托。旧方法需要如下代码:
var handler = this.PropertyChanged;
if (handler != null)
handler(…);
新方法更简单:
PropertyChanged?.Invoke(…)
新方法是线程安全的,因为编译器只生成一次评估PropertyChanged的代码,将结果保存在临时变量中。您需要显式调用Invoke方法,因为没有空条件委托调用语法PropertyChanged?(e)。
答案 2 :(得分:3)
这是对的。两者都有完全相同的结果。
鉴于您已正确初始化delTest
。
答案 3 :(得分:0)
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()
,因为您可以使用空检查,并且阅读代码的人可以更容易地看到正在使用委托。
空检查
MyDelegate mydelegate = null;
mydelegate?.Invoke("Reza");
mydelegate("Reza"); // Error: System.NullReferenceException