.NET中委托性能的演变
.NET中委托性能的演变
.NET中的委托#
.NET中的委托是一项重要功能,可以实现间接方法调用和函数式编程。
自.NET Framework 1.0起,委托在.NET中就支持多播(multicast)功能。通过多播,我们可以在单个委托调用中调用一系列方法,而无需自己维护方法列表。
即使在今天,委托的多播功能在桌面开发中仍然发挥着至关重要的作用。
让我们通过一个例子快速了解一下。
delegate void FooDelegate(int v);
class MyFoo
{
public FooDelegate? Foo { get; set; }
public void Process()
{
Foo?.Invoke(42);
}
}
我们简单地定义了一个带有单个参数v的委托,并在方法Process中调用了该委托。
要使用上面的代码,我们需要将一些目标添加到委托成员Foo中。
var obj = new MyFoo();
obj.Foo += v => Console.WriteLine(v);
obj.Foo += v => Console.WriteLine(v + 1);
obj.Foo += v => Console.WriteLine(v - 42);
obj.Process();
然后我们会得到如下预期的输出。
42
43
0
但是,在幕后发生了什么?
实际上,编译器会自动将我们的lambda表达式转换为方法,并使用静态字段缓存创建的委托,如下所示。
[CompilerGenerated]
internal class Program
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static FooDelegate <>9__0_0;
public static FooDelegate <>9__0_1;
public static FooDelegate <>9__0_2;
internal void <<Main>$>b__0_0(int v)
{
Console.WriteLine(v);
}
internal void <<Main>$>b__0_1(int v)
{
Console.WriteLine(v + 1);
}
internal void <<Main>$>b__0_2(int v)
{
Console.WriteLine(v - 42);
}
}
private static void <Main>$(string[] args)
{
MyFoo myFoo = new MyFoo();
myFoo.Foo = (FooDelegate)Delegate.Combine(myFoo.Foo, <>c.<>9__0_0 ?? (<>c.<>9__0_0 = new FooDelegate(<>c.<>9.<<Main>$>b__0_0)));
myFoo.Foo = (FooDelegate)Delegate.Combine(myFoo.Foo, <>c.<>9__0_1 ?? (<>c.<>9__0_1 = new FooDelegate(<>c.<>9.<<Main>$>b__0_1)));
myFoo.Foo = (FooDelegate)Delegate.Combine(myFoo.Foo, <>c.<>9__0_2 ?? (<>c.<>9__0_2 = new FooDelegate(<>c.