代码改变世界

C#中Lambda表达式的使用

2012-08-31 16:43  C#与.NET探索者  阅读(795)  评论(0编辑  收藏  举报
//where T : class , new() :说明泛型T是一个类,并且能在方法中实例化这个类。
public static List<T> ToList<T>(this DataTable dt) where T : class, new()
     {
 
     
    List<T> list;
       T model;
       List<PropertyInfo> infos;
       object tempValue;
 
            list = new List<T>();
            infos = new List<PropertyInfo>();
 
            Array.ForEach<PropertyInfo>(typeof(T).GetProperties(), p =>
            {
                if (dt.Columns.IndexOf(p.Name) != -1)
                {
                    infos.Add(p);
                }
            });
 
            foreach (DataRow dr in dt.Rows)
            {
                model = new T();
                infos.ForEach(p =>
                {
                    if (dr[p.Name] != DBNull.Value)
                    {
                        tempValue = dr[p.Name];
                        if (dr[p.Name].GetType() == typeof(DateTime))
                        {
                            tempValue = dr[p.Name].ToString();
                        }
                        p.SetValue(model, tempValue, null);
                    }
                });
                list.Add(model);
            }
 
            return list;
        }
//注意Action的用法。类似于delegate()委托的用法 ,它继承了delegate类。C# <wbr>lambda用法
 public class TestAction1 { public static void Main() { Action<string> messageTarget; if (Environment.GetCommandLineArgs().Length > 1) messageTarget = ShowWindowsMessage; else messageTarget = Console.WriteLine; messageTarget("Hello, World!"); } private static void ShowWindowsMessage(string message) { MessageBox.Show(message); } 
-------------------------------------------------
C# lambda操作符:
C#支持事件以内联(inline)方式处理,通过将一块代码语句赋给事件(使用匿名方法)。可不必如常规的处理:先建立一个独立的方法,之后再被委托封装,在事件触发时,该方法被底层委托调用。lambda表达式只不过是另一种更简洁的创建匿名方法并最终简化.net委托类型使用的一种方式。

c#2008也允许你使用表达式树将lambda表达式表示为一个内存对象。这对需要扩展已存在的lambdas功能来构建软件的第三方或使用LINQ编程时很有用。详细内容可参看sdk3.5文档。

lambda表达式可用在任何你使用匿名或强类型委托的地方。底层,c#编译器会使用合适的委托类型将lambda表达式转化为标准的匿名方法。

剖析lambda表达式:
一个lambda表达式构成结构:首先定义一个参数列表,后跟=>标记,再后跟一个语句集(或是单独的一条语句),这些语句会处理先前的参数,再一个较高的抽象级别上你可这样理解它:
ArgumentsToProcess => StatementsToProcessTheArguments;
lambda表达式的参数可是显式或隐式类型。当参数是隐式类型时,编译器能够通过上下文和底层委托类型决定参数的类型。但仍可在lambda表达是中显式定义每个参数的类型,需要用一对小括号将类型和变量名包起来。当参数只有一个时,显式指定参数类型可以不需要。为了一致性或美观,即使是隐式指定类型的参数或仅有一个显示类型参数时也最好每次都用括号将参数列表括起来。

当处理参数的语句是多行时,可用大括号将之括起来,所以lambda表达式的形式可以是这样的:
(ArgumentsToProcess) => {StatementsToProcessTheArguments}

无参情形:()=>StatementsToProcessTheArguments;

总之使用lambda表达式的理由是:提供一个干净,简洁的定义匿名方法(进而间接简化与委托的工作方式)的途径。

以下为示范:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LambdaDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            SomeEventOwner eventSender = new SomeEventOwner();
            
            //lambda表达式,作为一个委托,或是一个匿名函数注册在事件上。
            //以下演示各种lambda的形式:无参,无参单语句,隐含参数类型单语句,显式参数类型多语句
            eventSender.evt1 += () => { System.Console.WriteLine("this is no Parameter Lambd expression_r_r_r!"); };
            eventSender.evt1 += () => System.Console.WriteLine("this is no Parameter and sigleLine lambda demo");

            eventSender.evt2 += strFromEvent2 => System.Console.WriteLine(strFromEvent2);
            eventSender.evt3 += (string stringFromSender, int i) => {
                System.Console.WriteLine(stringFromSender);
                System.Console.WriteLine("some int type from sender,value is {0}", i);
                return null;//如果相应的事件的委托类型有返回值的话,lambda表达式可以有返回值。
            };
            //下面语句导致事件被调用,事件的激发,一般是由事件拥有者发起的。并由于其 自身的某些状态的改变引起
            //所以一般是事件拥有者的某个方法,属性例程被调用,导致事件间接激发。
            eventSender.ActivateAllEvent();
           
            System.Console.ReadLine();
        }
    }

   
     public delegate void NoParameterDelegateType();
     public delegate void MyDelegateType0(string arg0);
     public delegate string MyDelegateType1(string arg1,int arg2);

   

     class SomeEventOwner {

         public event NoParameterDelegateType evt1;
         public event MyDelegateType0 evt2;
         public event MyDelegateType1 evt3;

         public void ActivateAllEvent() {
            
            
             if (evt1 !=null){
                 evt1();
             }
             if (evt2 != null) { evt2("event2 happened!"); }
             if (evt3 != null) { evt3("event3 happened!", 0);
                 //随便传递的参数,实际应用中会传递有意义的信息。
             }
             
         }
     
     
     
     }

}