我发现了两种不同的方式来初始化一个代理:
创建一个新的操作或转换为Action.
Delegate foo = new Action(() => DoNothing(param)); Delegate bar = (Action)(() => DoNothing(param));
这两种语法有区别吗?
哪一个更好,为什么?
编辑:
在这个例子中使用delegate,因为语法对于使用lambda表达式调用BeginInvoke或Invoke等方法很有用,并且将lambda表达式转换为一个动作很重要
static main { Invoke((Action)(() => DoNothing())); // OK Invoke(new Action(() => DoNothing())); // OK Invoke(() => DoNothing()); // Doesn't compil } private static void Invoke(Delegate del) { }
但有兴趣的是,编译器授权这样做:
Action action = () => DoNothing(); Invoke(action);
解决方法
这两条指令没有区别.在这两个指令中,创建了一个新的Action实例.
下面的IL代码似乎证实了这一点.
控制台程序:
class Program { static void Main(string[] args) { Delegate barInit = (Action)(() => DoNothing()); Delegate fooInit = new Action(() => DoNothing()); } private static void DoNothing() { } }
IL代码:
// First instruction IL_0000: ldsfld class [mscorlib]System.Action CodeMachineTest.Program::'CS$<>9__CachedAnonymousMethodDelegate2' IL_0005: brtrue.s IL_0018 IL_0007: ldnull IL_0008: ldftn void CodeMachineTest.Program::'<Main>b__0'() // Create a new Action instance for the instruction (Action)(() => DoNothing()) IL_000e: newobj instance void [mscorlib]System.Action::.ctor(object,native int) IL_0013: stsfld class [mscorlib]System.Action CodeMachineTest.Program::'CS$<>9__CachedAnonymousMethodDelegate2' IL_0018: ldsfld class [mscorlib]System.Action CodeMachineTest.Program::'CS$<>9__CachedAnonymousMethodDelegate2' IL_001d: pop // Second instruction IL_001e: ldsfld class [mscorlib]System.Action CodeMachineTest.Program::'CS$<>9__CachedAnonymousMethodDelegate3' IL_0023: brtrue.s IL_0036 IL_0025: ldnull IL_0026: ldftn void CodeMachineTest.Program::'<Main>b__1'() IL_002c: newobj instance void [mscorlib]System.Action::.ctor(object,native int) IL_0031: stsfld class [mscorlib]System.Action CodeMachineTest.Program::'CS$<>9__CachedAnonymousMethodDelegate3' IL_0036: ldsfld class [mscorlib]System.Action CodeMachineTest.Program::'CS$<>9__CachedAnonymousMethodDelegate3' IL_003b: pop IL_003c: ret