C#强化系列文章四:匿名方法的使用

来源:互联网 发布:深入浅出python mobi 编辑:程序博客网 时间:2024/04/30 15:10
匿名方法相信很多人都听过,它是C#2.0的一个新特性,顾名思义,匿名方法就是没有名称的方法。那么在C#中的匿名方法有哪些好处,在C#中如何使用呢?
匿名方法最明显的好处就是可以降低另写一个方法的工作量,另外一个好处就是可以访问调用者的变量,降低传参数的复杂度,下面就通过一些使用例子来具体看看。
1、在事件中使用匿名方法
下面是一个定时器的小例子,我们常规的写法如下:

    class EventTest
    
{
        
public void Test()
        
{
            System.Timers.Timer timersTimer 
= new System.Timers.Timer();

            timersTimer.Enabled 
= true;
            timersTimer.Interval 
= 5000;
            timersTimer.Elapsed 
+= new System.Timers.ElapsedEventHandler(timersTimer_Elapsed);
            Console.ReadLine();
        }


        
void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        
{
            Console.WriteLine(System.DateTime.Now);
        }

    }

对于事件的处理我们需要单独写一个方法timersTimer_Elapsed,那么如果使用匿名方法,就可以省掉这个方法的定义,如下所示:
    class EventTest
    
{
        
public void Test()
        
{
            System.Timers.Timer timersTimer 
= new System.Timers.Timer();

            timersTimer.Enabled 
= true;
            timersTimer.Interval 
= 5000;
            timersTimer.Elapsed 
+=
                
delegate(object sender, System.Timers.ElapsedEventArgs e)
                
{
                    Console.WriteLine(System.DateTime.Now);
                }
;
            Console.ReadLine();
        }

    }

也就是把方法的实现直接写在内部。

2、在我们自己的代理中使用匿名方法
比如如下一个字符串转化的例子,按照传统的方法来写的话,对于每一种转化规则都需要单独定义一个方法:

    class DelegateTest
    
{
        
delegate string Convert(string text);

        
public void Test()
        
{
            
string strText = "123451234512345";

            Test2(ConvertA, strText);
            Test2(ConvertB, strText);
            Test2(ConvertC, strText);

            Console.ReadLine();
        }


        
private void Test2(Convert convert, string strText)
        
{
            Console.WriteLine(convert(strText));
        }


        
public string ConvertA(string strText)
        
{
            
return strText.Replace("1""A");
        }

        
public string ConvertB(string strText)
        
{
            
return strText.Replace("1""B");
        }

        
public string ConvertC(string strText)
        
{
            
return strText.Replace("1""C");
        }

    }
我们的例子中有三种规则,那么就要定义三个方法,如果使用匿名方法的话,代码就会很简单:
    class DelegateTest
    
{
        
delegate string Convert(string text);

        
public void Test()
        
{
            
string strText = "123451234512345";

            Test2(
delegate(string strText2)
                
{
                    
return strText2.Replace("1""A");
                }
, strText);
            Test2(
delegate(string strText2)
                
{
                    
return strText2.Replace("1""B");
                }
, strText);
            Test2(
delegate(string strText2)
                
{
                    
return strText2.Replace("1""C");
                }
, strText);

            Console.ReadLine();
        }


        
private void Test2(Convert convert, string strText)
        
{
            Console.WriteLine(convert(strText));
        }

    }

3、优化例子2,不再传递参数
在例子2中我们是把参数传到你们方法内部的,其实在匿名方法内部可以直接取得当前调用者的变量,节省了传递参数的代码量:
    class AnonTest
    
{
        
delegate string Convert();

        
public void Test()
        
{
            
string strText = "123451234512345";

            Test2(
delegate()
                
{
                    
return strText.Replace("1""A");
                }
);
            Test2(
delegate()
                
{
                    
return strText.Replace("1""B");
                }
);
            Test2(
delegate()
                
{
                    
return strText.Replace("1""C");
                }
);

            Console.ReadLine();
        }


        
private void Test2(Convert convert)
        
{
            Console.WriteLine(convert());
        }

    }
这样一来,代码是不是看起来很整洁:)

当然代码虽然看起来很少,实际上编译器在编译时还是会生成其他方法的。也就是说匿名方法可以减少代码量,节省开发时间,但是对于性能方法没有什么提升的。
我们通过IL DASM工具可以查看一下AnonTest类编译后的代码,会发现增加一个新类,在这个类里面生成了三个方法和一个同名的strText变量:


然后在Test方法中会调用这些新生成的方法,Test如下所示:
.method public hidebysig instance void  Test() cil managed
{
  
// 代码大小       83 (0x53)
  .maxstack  4
  .locals init ([
0class AnonMethod.AnonTest/'<>c__DisplayClass3' '<>8__locals4')
  IL_0000:  newobj     instance 
void AnonMethod.AnonTest/'<>c__DisplayClass3'::.ctor()
  IL_0005:  stloc.
0
  IL_0006:  nop
  IL_0007:  ldloc.
0
  IL_0008:  ldstr      
"123451234512345"
  IL_000d:  stfld      
string AnonMethod.AnonTest/'<>c__DisplayClass3'::strText
  IL_0012:  ldarg.
0
  IL_0013:  ldloc.
0
  IL_0014:  ldftn      instance 
string AnonMethod.AnonTest/'<>c__DisplayClass3'::'<Test>b__0'()
  IL_001a:  newobj     instance 
void AnonMethod.AnonTest/Convert::.ctor(object,
                                                                        native 
int)
  IL_001f:  call       instance 
void AnonMethod.AnonTest::Test2(class AnonMethod.AnonTest/Convert)
  IL_0024:  nop
  IL_0025:  ldarg.
0
  IL_0026:  ldloc.
0
  IL_0027:  ldftn      instance 
string AnonMethod.AnonTest/'<>c__DisplayClass3'::'<Test>b__1'()
  IL_002d:  newobj     instance 
void AnonMethod.AnonTest/Convert::.ctor(object,
                                                                        native 
int)
  IL_0032:  call       instance 
void AnonMethod.AnonTest::Test2(class AnonMethod.AnonTest/Convert)
  IL_0037:  nop
  IL_0038:  ldarg.
0
  IL_0039:  ldloc.
0
  IL_003a:  ldftn      instance 
string AnonMethod.AnonTest/'<>c__DisplayClass3'::'<Test>b__2'()
  IL_0040:  newobj     instance 
void AnonMethod.AnonTest/Convert::.ctor(object,
                                                                        native 
int)
  IL_0045:  call       instance 
void AnonMethod.AnonTest::Test2(class AnonMethod.AnonTest/Convert)
  IL_004a:  nop
  IL_004b:  call       
string [mscorlib]System.Console::ReadLine()
  IL_0050:  pop
  IL_0051:  nop
  IL_0052:  ret
}
 // end of method AnonTest::Test
 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果6内存虚满怎么办 监控主机密码忘了怎么办 加购物车不下单怎么办 绑定qq账号消息不见了怎么办 现在的注册微信怎么办 爱奇艺手机号码被别人绑定了怎么办 手机号码换了支付宝账号怎么办 qq换手机号了怎么办呢 公司被注销了公众号怎么办 qq号被限制查找怎么办 qq号别人查找不到怎么办 qq邮箱已被注册怎么办 微信付款没网络怎么办 天猫买的假货店铺关门了怎么办 鞋小了半码怎么办 迅雷会员种子不能加速怎么办 迅雷会员为什么不能加速怎么办 持有st创智股票怎么办 租的房子床坏了怎么办 宜家定时器不响怎么办 新插座插不进去怎么办 本溪人社app打不开怎么办 南宁电车超过上牌时间怎么办 苹果6s降频怎么办 0首付手机还不起怎么办 乐才app登录不上怎么办 买了笔记本网要怎么办? 电脑连接不上网络怎么办 电脑上没网络了怎么办 手机返回键不好使怎么办 笔记本无线网连接受限怎么办 魅族打电话图标没有了怎么办 京东价格保护后发票怎么办 淘宝未满十八岁怎么办 SVN提交时代码冲突怎么办 京东自营没货了怎么办 京东下了单 没货怎么办 万达广场购物卡怎么办 京东白条没额度怎么办 京东退款还收到货怎么办 退货不想要货了怎么办