Lambda表达式简介:
MSDN定义:Lambda 表达式是一种可用于创建委托或表达式目录树类型的匿名函数。
介绍
1.lambda表达式是匿名函数,只不过长得不太像而已,可以看成是进化版。
2.lambda表达式是用来创建委托或者目录树的匿名函数
使用场景:
可以在需要委托值的任何地方(也就是在可以使用匿名方法的任何地方)使用这些表达式。
我的理解:
其实Lambda表达式就是匿名方法。
其中使用Lambda表达式来创建委托实例,我们却没有指出创建的委托类型,其中编译器会帮助我们去推断委托类型,从而简化我们创建委托类型所需要的代码,从而更加简洁。
所以Lambda表达式可以总结为——它是在匿名方法的基础上,再进一步地简化了创建委托实例所需要的代码。
匿名方法可以简明的忽略参数,但Lambda表达式不具备这一特性。
Button btn=new Button();
Btn.Text=“click me”;
Btn.Click+=delegate{console.WriteLine(“LogPlain”);};//忽略了我们经常使用的参数delegate(object sender,EventArgs e){…}
Lambda表达式使用演示
static void Main(string[] args)
{
// Lambda表达式的演变过程
// 下面是C# 1中创建委托实例的代码
Func<string, int> delegatetest1 = new Func<string, int>(Callbackmethod);
// ↓
// C# 2中用匿名方法来创建委托实例,此时就不需要额外定义回调方法Callbackmethod
Func<string, int> delegatetest2 = delegate(string text)
{
return text.Length;
};
// ↓
// C# 3中使用Lambda表达式来创建委托实例
Func<string, int> delegatetest3 = (string text) => text.Length;
// ↓
// 如果Lambda表达式只需一个参数,并且那个参数可以隐式指定类型时,
// 此时可以把圆括号也省略,简化为:
Func<string, int> delegatetest = text => text.Length;
// 调用委托
Console.WriteLine("使用Lambda表达式返回字符串的长度为: " + delegatetest("learning hard"));
Console.Read();
}
/// <summary>
/// 回调方法
/// 如果使用了Lambda表达式和匿名函数,此方法就不需要额外定义
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private static int Callbackmethod(string text)
{
return text.Length;
}
Lambda结合Action和Func的使用
Action<string> action = (str) => Console.WriteLine("Task={0}, str={1}, Thread={2}", Task.CurrentId, str, Thread.CurrentThread.ManagedThreadId);
Func<int, int> negate =(n) =>{
Console.WriteLine("Task={0}, n={1}, Thread={2}", Task.CurrentId, n, Thread.CurrentThread.ManagedThreadId);
return -n;
};
Task<int>.Factory.StartNew(() => negate(6))
.ContinueWith(f => action("x"))
.Wait();
Lambda表达式的使用
主要的是在Linq表达式的使用,以及对扩展方法上的运用等
例如:
List list=new List();
list.Add(2);
list.Add(3);
list.Where(x=>x%2==0);
where方法其实就是一个扩展方法
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
总结
- 匿名函数不等于匿名方法,匿名函数包含了匿名方法和lambda表达式这两种概念。
匿名函数:{匿名方法,lambda表达式}
2.lambda作为表达式,可以被C#编译器转换为委托,也可以被编译器转换为表达式树,匿名方法只能转换为委托。
两者的共通点是都能被编译器转换成为委托,lambda表达式能完成几乎所有匿名方法能完成的事。
延伸
Linq查询操作符
string[] words = { "zero","one", "two", "three", "four" };
int[] numbers = { 0, 1, 2, 3, 4 };
1.聚合
numbers.Sum();
numbers.Average();
numbers.Count();
numbers.LongCount(x => x % 2 == 0);
words.Min();
words.Max();
numbers.Aggregate((a, b) => (a + b));
2.链接
numbers.Concat(new[] { 2, 3, 4, 5, 6 });
3.转换
words.Cast<string>() //遍历时遇到转换失败的地方,会抛出异常
words.OfType<string>()
numbers.ToArray();
numbers.ToList();
words.ToDictionary(w => w.Substring(0, 2));
numbers.Concat(new[] { 2, 3, 4, 5, 6 });
4.元素操作符
words.ElementAt(2);
words.ElementAtOrDefault(10);
words.First();
words.First(w => w.Length == 3);
words.First(w => w.Length == 10); //异常:没有匹配的元素
words.FirstOrDefault (w => w.Length == 10); //null
words.Last(); //"four“
words.Single(); //异常:不止一个元素
words.SingleOrDefault(); //异常:不止一个元素
words.Single(word => word.Length == 5); //“three“ 返回唯一元素
words.Single(word => word.Length == 10); //异常:没有匹配的元素
words.SingleOrDefault(w => w.Length == 10); //null 返回唯一元素
5.相等操作
words.SequenceEqual(new[]{“ZERO”,“ONE”,“TWO”,“THREE”,“FOUR”},StringComparer.OrdinalIgnoreCase);
6.生成
numbers.DefaultIfEmpty(); //0, 1, 2, 3, 4
Enumerable.Range(0, 100);
Enumerable.Repeat(25, 2);//生成包含重复值的序列
Enumerable.Empty<int>();//生成任意类型的空序列
7.分组
words.GroupBy(word => word.Length);
8.连接
words.Join(allStrings, name => name[0], color => allStrings[0],(name, color) => name + " - " + color);
words.GroupJoin
9.分部
words.Take(2); //"zero", "one"
words.Skip(2); //"two","three", "four"
words.TakeWhile(word => word.Length <= 4); //"zero", "one", "two"
words.SkipWhile(word => word.Length <= 4); //"three","four“
10.投影
words.Select(word => word.Length);// 4, 3, 3, 5, 4
words.Select((word, index) => index.ToString() + ": " + word); //"0: zero", "1: one", "2: two","3: three", "4: four"
words.SelectMany(word => word.ToCharArray());//'z', 'e', 'r', 'o', 'o', 'n', 'e', 't', 'w', 'o', 't','h', 'r', 'e', 'e', 'f', 'o', 'u', 'r'
11.数量
words.All(word => word.Length > 3); //false("one"和"two"的确包含3个字母)
words.All(word => word.Length > 2); //true
words.Any(); //true(序列不为空)
words.Any(word => word.Length == 6); //false(没有6个字母的单词)
words.Any(word => word.Length == 5); //true("three"满足这个条件)
words.Contains("FOUR"); //false
words.Contains("FOUR",StringComparer.OrdinalIgnoreCase); //true
12.过滤
words.Where(word => word.Length > 3); //"zero", "three", "four“
13.基于集的操作符
"abbc".Distinct(); //"a", "b", "c"
"abbc".Intersect("cd"); //"c"
"abbc".Union("cd");//"a", "b", "c", "d"
"abbc".Except("cd"); //"a", "b"
"cd".Except("abc"); //"d“
14.排序
words.OrderBy(word => word);
words.Reverse();
words.OrderByDescending(word => word.Length);
有部分内容是摘抄的深入浅出C#,附上PDF下载。