匿名方法

    在原来的 C#版本中我们是这样定义Event:
this.Button1.Click += new EventHandler(Button1_Click)
private void Button1_Click(object sender,EventArgs e)
{
        //…
}
    在现在的 2.0版本中有了匿名方法,我们可以将上面的代码这样编写
    this.Button1.Click += delegate{
        //…
}
 
从上面的代码示例可以看出匿名方法的几个要点
1、 匿名方法只存在方法,但没有名字
2、 委托有一种桥接的概念,而匿名方法就是要将这个桥接简化。换句话说:匿名方法允许我们以一种“内联”的方式来编写方法代码,将代码直接与委托实例相关联,从而使得委托实例化的工作更加直观和方便
3、 匿名方法直接与委托实例相关联
 
在匿名方法中,有几点问题要注意:
1、 参数列表,看如下代码:
static void Main(string[] args)
{
     MyDelegate MyDele = delegate(int i) { Console.WriteLine("hello KiddLee"); };
}
delegate void MyDelegate(int i);
    匿名方法可以在 delegate关键字后跟一个参数列表(可以不指定),后面的代码块则可以访问这些参数,如果不指定的话也是可以的,如下代码编译时也可以通过。
static void Main(string[] args)
{
     MyDelegate MyDele = delegate{ Console.WriteLine("hello KiddLee"); };
}
delegate void MyDelegate(int i);
    注意:不指定参数列表和参数列表为空是不一样的,如下
    //不指定参数列表,对于 MyDelegate来说这种情况是正确的
    MyDelegate MyDele = delegate{ Console.WriteLine("hello KiddLee"); };
    //参数列表为空,对于 MyDelegate来说这种情况是错误的
    MyDelegate MyDele = delegate(){ Console.WriteLine("hello KiddLee"); };
2、 匿名方法的返回值
如果委托类型的返回值类型为 void,匿名方法里不能返回任何值
delegate void MyDelegate();
 
        static void Main(string[] args)
        {
            MyDelegate mydele = delegate
            {
                return;
            };
    }
但是如果委托类型的返回值类型不为 void,匿名方法返回值也不能为void
delegate int MyDelegate();
 
        static void Main(string[] args)
        {
            MyDelegate mydele = delegate
            {
                return 100;
            };
    }
3、 外部变量
匿名方法有时会使用一些局部变量和参数,这些局部变量和参数被称为“ 匿名方法的外部变量”。
外部变量的生存期会由于“匿名方法的捕获效益”而延长,直到委托实例不被引用为止。
public delegate void MyDelegate();
 
        static void Main(string[] args)
        {
            int test = 55;
            Console.WriteLine(test);
            Function(test);
            Console.WriteLine(test);
            Console.Read();
        }
 
        static void Function(int test)
        {
            MyDelegate mydele = delegate
            {
                Console.WriteLine(test);
                test = 11;
                Console.WriteLine(test);
            };
            Console.WriteLine("Before Invoke:" + test);
            mydele.Invoke();
            Console.WriteLine("After Invoke:" + test);
     }
输出结果如下:
55
Before Invoke:55
55
11
After Invoke:11
55
匿名方法的机制:
C#2.0中的匿名方法只是通过编译器简化了委托实例化的工作,不存在性能上的差别。下面来看看以下几点:
1、 静态方法中的匿名方法
delegate void MyDelegate();
static void Function(int test)
        {
            MyDelegate mydele = delegate
            {
                Console.WriteLine("Hello KiddLee");
            };
     }

反编译的结果是:


 
.method private hidebysig static void Function(int32 test) cil managed
{
 // Code size        34 (0x22)
 .maxstack 3
 .locals init ([0] class ConsoleCSharpStudy1.Program/MyDelegate mydele)
 IL_0000: nop
 IL_0001: ldsfld      class ConsoleCSharpStudy1.Program/MyDelegate ConsoleCSharpStudy1.Program::'<>9__CachedAnonymousMethodDelegate1'
 IL_0006: brtrue.s    IL_001b
 IL_0008: ldnull
 IL_0009: ldftn      void ConsoleCSharpStudy1.Program::'<Function>b__0'()
 IL_000f: newobj      instance void ConsoleCSharpStudy1.Program/MyDelegate::.ctor(object,
                                                                                   native int)
 IL_0014: stsfld      class ConsoleCSharpStudy1.Program/MyDelegate ConsoleCSharpStudy1.Program::'<>9__CachedAnonymousMethodDelegate1'
 IL_0019: br.s        IL_001b
 IL_001b: ldsfld      class ConsoleCSharpStudy1.Program/MyDelegate ConsoleCSharpStudy1.Program::'<>9__CachedAnonymousMethodDelegate1'
 IL_0020: stloc.0
 IL_0021: ret
} // end of method Program::Function
    从反编译的结果可以看出:编译后编译器自动生成了一个 <Function>b__0'()方法,再来看看这个方法的反编译结果:
.method private hidebysig static void '<Function>b__0'() cil managed
{
 .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
 // Code size        13 (0xd)
 .maxstack 8
 IL_0000: nop
 IL_0001: ldstr       "Hello KiddLee"
 IL_0006: call        void [mscorlib]System.Console::WriteLine(string)
 IL_000b: nop
 IL_000c: ret
} // end of method Program::'<Function>b__0'
    实际上就是执行 Console.WriteLine( "Hello KiddLee")
 
2、 实例方法中的匿名方法
void Function2()
        {
            MyDelegate mydele = delegate
            {
                Console.WriteLine("Hello KiddLee");
            };
     }

再来看看反编译结果:


 


Function2的反编译结果是:
.method private hidebysig instance void Function2() cil managed
{
 // Code size        34 (0x22)
 .maxstack 3
 .locals init ([0] class ConsoleCSharpStudy1.Program/MyDelegate mydele)
 IL_0000: nop
 IL_0001: ldsfld      class ConsoleCSharpStudy1.Program/MyDelegate ConsoleCSharpStudy1.Program::'<>9__CachedAnonymousMethodDelegate3'
 IL_0006: brtrue.s    IL_001b
 IL_0008: ldnull
 IL_0009: ldftn      void ConsoleCSharpStudy1.Program::'<Function2>b__2'()
 IL_000f: newobj      instance void ConsoleCSharpStudy1.Program/MyDelegate::.ctor(object,
                                                                                   native int)
 IL_0014: stsfld      class ConsoleCSharpStudy1.Program/MyDelegate ConsoleCSharpStudy1.Program::'<>9__CachedAnonymousMethodDelegate3'
 IL_0019: br.s        IL_001b
 IL_001b: ldsfld      class ConsoleCSharpStudy1.Program/MyDelegate ConsoleCSharpStudy1.Program::'<>9__CachedAnonymousMethodDelegate3'
 IL_0020: stloc.0
 IL_0021: ret
} // end of method Program::Function2
    有红色的部分可以看出,编译后生成了一个 <Function2>b__2'(),再看看此函数的反编译结果:
    .method private hidebysig static void '<Function2>b__2'() cil managed
{
 .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
 // Code size        13 (0xd)
 .maxstack 8
 IL_0000: nop
 IL_0001: ldstr       "Hello KiddLee"
 IL_0006: call        void [mscorlib]System.Console::WriteLine(string)
 IL_000b: nop
 IL_000c: ret
} // end of method Program::'<Function2>b__2'
 
3、 匿名方法中的外部变量
void Function2()
        {
            int y = 3;
            MyDelegate mydele = delegate
            {
                Console.WriteLine(y);
            };
     }
    看看 Function2生成的反编译代码:





.method private hidebysig instance void Function2() cil managed
 
{
 // Code size        29 (0x1d)
 .maxstack 3
 .locals init ([0] class ConsoleCSharpStudy1.Program/MyDelegate mydele,
           [1] class ConsoleCSharpStudy1.Program/'<>c__DisplayClass4' '<>8__locals5')
 IL_0000: newobj      instance void ConsoleCSharpStudy1.Program/'<>c__DisplayClass4'::.ctor()
 IL_0005: stloc.1
 IL_0006: nop
 IL_0007: ldloc.1
 IL_0008: ldc.i4.3
 IL_0009: stfld       int32 ConsoleCSharpStudy1.Program/'<>c__DisplayClass4'::y
 IL_000e: ldloc.1
 IL_000f: ldftn       instance void ConsoleCSharpStudy1.Program/'<>c__DisplayClass4'::'<Function2>b__3'()
 IL_0015: newobj      instance void ConsoleCSharpStudy1.Program/MyDelegate::.ctor(object,
                                                                                   native int)
 IL_001a: stloc.0
  IL_001b: nop
 IL_001c: ret
} // end of method Program::Function2
    其中<>c__DisplayClass4是编译时生成的类型,而<Function2>b__3'()是这个类型下的方法,来看看它的反编译代码:
.method public hidebysig instance void '<Function2>b__3'() cil managed
{
 // Code size        14 (0xe)
 .maxstack 8
 IL_0000: nop
 IL_0001: ldarg.0
 IL_0002: ldfld       int32 ConsoleCSharpStudy1.Program/'<>c__DisplayClass4'::y
 IL_0007: call        void [mscorlib]System.Console::WriteLine(int32)
 IL_000c: nop
 IL_000d: ret
} // end of method '<>c__DisplayClass4'::'<Function2>b__3'
 
由此可以看出匿名方法可以说只是一个委托在 C#2.0中的写法,不会带来太多的性能提升
 

 


 




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值