lamba表达式的个人见解
Lambda 表达式”是一个匿名函数,它可以包含表达式和语句,并且可用于创建委托或表达式树类型。
所有 Lambda 表达式都使用 Lambda 运算符 =>,该运算符读为“goes to”。该 Lambda 运算符的左边是输入参数(如果有),右边包含表达式或语句块。Lambda 表达式 x => x * x 读作“x goes to x times x”。可以将此表达式分配给委托类型,如下所示:
delegate int del(int i,int j); static void Main(string[] args) { del myAdd=(x,y)=>x+y; int j = myAdd(1, 2); Console.WriteLine(j); }
这里Lambda 表达式用于创建委托.
下面看下创建表达式树类型
public delegate int myAdd(int x,int y); static void Main(string[] args) { Expression<myAdd> myET = (x,y) => x+y; Console.WriteLine(myET.Compile()(1, 2)); }
对于表达式树类型,这里不作详细介绍!他的主要功能是对表达式作一些处理!
看完上面的例子,大体上可以知道lamba表达式是和委托,匿名方法联系在一起的!
以我的认识角度来看,完全可以把lamba表达式看作一个方法体!他有参数,有表达式或者语句块!或者说他本身就是一个函数,只不过他做了一些简写!
lamba表达式比较常见的用法是和范型一起使用.请看下面的例子:
public delegate T mySum<T>(T x, T y);
public delegate void myPrint<T>(mySum<T> mysum);
static void Main(string[] args)
{
Show((x, y) => (x + y), (f) => { Console.WriteLine(f(11,22)); });
}
static void Show(mySum<int> test,myPrint<int> print)
{
Console.WriteLine("mySum is " + test(11, 22));
Console.Write("myPrint is " );
print((x, y) => x + y);
}
刚开始可能这个例子有些复杂,仔细分析下还是比较简单,首先声明两个委托,一个是通常的参数,一个是委托类型参数,其实委托类型参数和通常的参数都看成参数更易于理解,我们需要习惯于委托这种变量把他和一般的变量同等看待!然后声明一个Show的方法,有两个参数.当我们去调用时,委托类型参数直接传递lamba表达式就行了!这里再次看出lamba表达式就是委托,就是方法体!
在看下面一个例子
public delegate T1 mySum<T1,T2>(T1 x, T2 y);
static void Main(string[] args)
{
Show((x, y) => ((int.Parse(x.ToString()) + int.Parse(y.ToString())).ToString()));
Show((x, y) => (int.Parse(x.ToString()) + int.Parse(y.ToString())));
}
static void Show(mySum<string, string> test)
{
Console.WriteLine("mySum is " + test("11", "22"));
}
static void Show(mySum<int,int> test)
{
Console.WriteLine("mySum is " + test(11, 22));
}
//static void Show(mySum<int, string> test)
//{
// Console.WriteLine("mySum is " + test(11, "22"));
//}
从这个例子看出lamba表达式的类型推断非常明显的第一个show将调用string参数的方法,第二个将会调用int参数的方法.类型推断包括了参数的类型和返回值类型.如果将注释部分打开的话就会出现编译错误.
编译器无法认知将调用哪个方法!
在实际的使用中lamba表达式大多都是应用于ORM框架里的查询的!更确切地说,是应用于集合类型的筛选与查找!linq给我们提供了许多的扩展方法,像select,where,take之类的很多.而这些方法的参数都是委托!
所以大部分时候,都是写lamba表达式的!而我在这里想说的是,我们只是传递一个方法体!里面的具体实现我们并不清楚.
请看下面的例子:
static void Main(string[] args)
{
List<int> lists = new List<int>();
lists.Add(1); lists.Add(3); lists.Add(7); lists.Add(5); lists.Add(4); lists.Add(19); lists.Add(2);
lists=lists.MyWhere(c => { if (c > 5) { return c; } return 0; });
foreach (var item in lists)
{
Console.WriteLine(item);
}
}
}
public static class MyExtension
{
public delegate T myFilter<T>(int i);
public static List<int> MyWhere(this List<int> lists, myFilter<int> myfilter)
{
List<int> newlists = new List<int>();
foreach (var item in lists)
{
if (myfilter(item) != 0)
{
newlists.Add(myfilter(item));
}
}
return newlists;
}
}
这个我想说明的是Mywhere虽然调用时我们传递的lamba表达式,但是里面的实现功能是封装的!我想自带的扩展方法也是怎么做的!
我对lamba表达式是怎么看的,1.他简化代码.
2.它就是方法体,就是匿名发法.只不过就是以前我们调用方法的时候需写全一个函数,然后在调用.
3.lamba表达式确实对开发节省了很多时间,我想它的最大优点表现在对集合类型的操作非常方便.
4.lamba表达式有一个缺点,就是无法调试.这确实很不好!