匿名方法

 

 

C#2.0中,匿名方法是通过delegate来实现的,可以看成是delegate功能的一种扩展。
delegate就如同一个盒子的模型,可以照模型复制一个盒子(产生对象),打上标签(对象名),装进东西(符合签名的方法),然后用它做点什么.

C#早期版本中delegate的用法:
在C# 1.X中,只有一种方法可以实例化delegate,如同实例化对象一样,将一个符合delegate签名的方法作为参数传给delegate:

delegate   int  Sample( int  x,  int  y);

class  List1
{
    
static   int  Plus( int  x,  int  y)
    {
        
return  x  +  y;
    }

    
static   string  myField  =  "Hello" ;

    
public   static   void  Main()
    {
        Sample 
=   new  Sample(List1.Plus);
        
int  result  =  f( 2 3 );
        System.Console.WriteLine(result);

        
string  refToMyField  =  List1.myField;
        System.Console.WriteLine(refToMyField);

        
string  variable  =  "polarlights" ;
        System.Console.WriteLine(variable);
    }
}

在List1类中,Sample委托的实例f引用了静态方法Plus(int x, int y).在C#2.0中,可以用匿名方法来实例化一个delegate

匿名方法


在C# 2.0中的匿名方法示例如下:

delegate int Sample(int x, int y);

class List2
{
    
static int Plus(int x, int y)
    {
        
return x + y;
    }

    
static string myField = "Hello";

    
public static void Main()
    {
        Sample f 
= new Sample(List2.Plus);
        
int result = f(23);
        System.Console.WriteLine(result);

        
string refToMyField = List2.myField;
        System.Console.WriteLine(refToMyField);

        
string variable = "polarlights";     
        System.Console.WriteLine(variable);

        Sample anonymousFunction 
= delegate(int x, int y) { return x * y; }; //匿名方法
        int dynamicResult = anonymousFunction(34);
        System.Console.WriteLine(dynamicResult);
    }
}


需要注意的是:
1.在C#2.0中,delegate关键字有了新的意义,当编译器发现它出现在一个方法体内时(上例出现在Main()方法内),编译器会期望它后面出现一个匿名方法体(上例中是{return x*y})。
2.可以将一个匿名方法赋给一个delegate实例(上例中赋给了Sample的实例anonymousFunction )
3.可以这样理解为何称其为匿名方法:这个方法定义在一个现有方法的内部而且自己没有名字。我们可以调用它,因为一个delegate的实例引用了它

另外,在匿名方法 Sample anonymousFunction = delegate(int x, int y) { return x * y; };中,只指定了参数类型,没有指定返回值的类型,因为编译器知道在Sample委托中定义的类型是int型,如果尝试将其改为:Sample anonymousFunction = delegate(int x, int y) { return "123"; };则编译器会提示"无法将匿名方法块转换为委托类型“Sample”,原因是块中的某些返回类型不能隐式转换为委托返回类型" 。

匿名方法中的参数
1.匿名方法可以接受实参,但什么都不做:

delegate   int  Sample( int  x,  int  y);

class  List3
{
    
public   static   void  Main()
    {
        Sample anonymousFunction 
=   delegate ( int  x,  int  y)
        {
            
return  System.DateTime.Now.Millisecond;   // 表示当前时间的毫秒部分
   };
        
int  dynamicResult  =  anonymousFunction( 3 4 );
        System.Console.WriteLine(dynamicResult);   // 将显示当前时间的毫秒部分

  }
}

 2.在匿名方法声明中可以将形参忽略,虽然其对应的delegate定义是有参数的:

delegate int Sample(int x, int y);

class List4

    
public static void Main()
    {
        Sample anonymousFunction 
= delegate     //忽略了参数

        {
            
return System.DateTime.Now.Millisecond;   // 表示当前时间的毫秒部分
    };
       
int dynamicResult = anonymousFunction(34);
        System.Console.WriteLine(dynamicResult);   // 将显示当前时间的毫秒部分

  }
}

3.在匿名方法声明中 ,要么使其形参为空,如同上例所示,要么使其形参完整,符合与其对应的delegate的定义。否则会出编译错误:

delegate int Sample(int x, int y);
 
class List5

public static void Main()
    {
        Sample anonymousFunction 
= delegate(int x)
        {
            
return x * 2;
        };
    }
}

编译器会提示"法将匿名方法块转换为委托类型“Sample”,原因是指定块的参数类型与委托参数类型不匹配"

匿名方法与泛型:
如下所示,匿名方法也可以声明泛型参数<T>.一个带泛型参数的匿名方法可以赋给一个同类型的delegate实例,只需确保其符合delegate签名即可

using System;
class List6<T>
{
    
delegate void DelegateType(T t);
    
internal void UneMethode(T t)
    {
        DelegateType delegateInstance 
= delegate(T arg) { Console.WriteLine"Hello args:{0}"arg.ToString()); };
        delegateInstance(t);
    }
}

class Program
{
    
static void Main()
    {
        List6
<double> inst = new List6<double>();
        inst.UneMethode(
5.5);
        Console.ReadKey();
    }
}

该例中定义了一个泛型类List6,一个泛型委托DelegateType和一个泛型匿名方法(没有名字的东东),然后在Main()方法中实例化泛型类List6,类型指定为double型,将double型实参5.5传入内部泛型实例方法UneMethode中,该方法将一个泛型匿名方法赋给一个泛型委托DelegateType的实例,并用该实例调用泛型匿名方法。

适用匿名方法的情形:
 个人认为,在需要调用一些小方法的时候,比较适合用匿名方法.比如下面的例子,在线程开始时调用匿名方法,显示当前线程哈希值和相关信息:

using System;
using System.Threading;
class Program
{
    
static void Main()
    {
        Thread thread 
= new Thread(delegate()                     
    //这里调用的是Thread类构造函数第一形态--ParameterizedThreadStart 委托,匿名方法代之
    //.NET Framework 2.0新增,详见MSDN 2005类库参考
        {                                                                                              
         Console.WriteLine("ThreadHashCode:{0} Hello"Thread.CurrentThread.GetHashCode());
        });
        thread.Start();
        Console.WriteLine("
ThreadHashCode:{0} polarlights"Thread.CurrentThread.GetHashCode());
        Console.ReadKey();
    }
}

 亦可用于事件的调用:

using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Text;
using  System.Windows.Forms;

namespace  WindowsApplication1
{
    
public  partial  class  Form1 : Form
    {
        
public  Form1()
        {
            InitializeComponent();
            button1.Click 
+=   delegate ( object  sender, EventArgs args)
            {
                MessageBox.Show(
"button1 Clicked " );
            };
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值