c# lambda
1.lambda表达式是匿名函数的一个变体,一开始是为了委托服务的,后面就千变万化了。lambda表达式其实就是一个匿名方法。
public class MyLambda { public delegate void NoReturnNoPara(); public delegate void NoReturnNoWithPara(int id, string name); public delegate int WithReturnNoPara(); // public delegate Delet WithReturnWithPara(); public void Show() { { NoReturnNoWithPara noReturnNoPara = new NoReturnNoWithPara(Study); noReturnNoPara(123, "阿发"); } {
int i=0;
//lamdaba可以省略参数类型,根据委托的约束的可以自动推算出来,这是一个语法糖(就是编译器提供的快捷功能)
NoReturnNoWithPara noReturnNoPara =
new NoReturnNoWithPara((id, name) => { Console.WriteLine($"This is {id}-{name}");
int j=i;//可以访问局部变量 }); noReturnNoPara(123, "阿发"); }
{ //如果方法体只有一行,可以省略大括号和分号。 NoReturnNoWithPara noReturnNoPara = new NoReturnNoWithPara((id, name) => Console.WriteLine($"This is {id}-{name}")
); noReturnNoPara(123, "阿发"); } { //实例化委托的时候,可以省略掉new NoReturnNoWithPara --这也是语法糖。 NoReturnNoWithPara noReturnNoPara = (id, name) => Console.WriteLine($"This is {id}-{name}"); noReturnNoPara(123, "阿发"); } { //注意:基于lambda表达式注册的多播委托是无法移除的。因为任何一个lambda表达式都是独立的,所以无法移除,只能添加。 NoReturnNoWithPara method = (id, name) => Console.WriteLine($"This is {id}-{name}"); method += (id, name) => Console.WriteLine($"This is {id}-{name}"); method -= (id, name) => Console.WriteLine($"This is {id}-{name}"); method(123, "阿发"); } { //其他lambda写法 //Func存在0到16个参数,不带返回值 泛型委托 Action<string> action = s => { Console.WriteLine("e"); }; Action action0 = () => { Console.WriteLine("e"); }; //如果方法体只有一行,可以省略掉大括号,分号,和return //Func存在0到16个参数,带返回值 泛型委托 Func<int> func = () => DateTime.Now.Year; Func<int, string> func1 = (i) => i.ToString(); } } private void Study(int id, string name) { Console.WriteLine($"This is {id}-{name}"); } }
上面的代码都是lambda表达式和委托在一起使用,但是其实lambda表达式不止是和委托一起使用。
public class LambdaOther { /// <summary> /// 这个就是属性 /// </summary> public string Name => "test"; public string Remark { get => "tets"; } public string Get() => "返回string的Get方法"; #region Id和下面id1是一样的,只不过是写法不同 public int Id { get; set; } = 123; private int _id1 = 123; public int Id1 { get { return _id1; } set { _id1 = value; } } #endregion }
lambda表达式也可以表达成表达式目录树
看下面的代码,如果我们要去数据库查询数据的话,肯定是要通过sql,那么下面的lambda表达式(s => s.Id > 100 && s.Name.Contains("1"))是如何转换成sql的呢?
//通过linq去数据库查询数据 var userDbSet = new List<Student>().AsQueryable(); var userList = userDbSet.Where(s => s.Id > 100 && s.Name.Contains("1"));
lambda实际上是一个方法,而方法是不可能变成sql的,这里面有涉及到了表达式目录树。
linq中的where方法具体的一些参数如下:
// // 摘要: // Filters a sequence of values based on a predicate. // // 参数: // source: // An System.Linq.IQueryable`1 to filter. // // predicate: // A function to test each element for a condition. // // 类型参数: // TSource: // The type of the elements of source. // // 返回结果: // An System.Linq.IQueryable`1 that contains elements from the input sequence that // satisfy the condition specified by predicate. // // 异常: // T:System.ArgumentNullException: // source or predicate is null. public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate);
所以lambda可以快捷声明表达式目录树,在这里它也是通过表达式目录树来转换成sql到数据库来查询数据的。
//这里的lambda就是一个方法 Func<Student, bool> func = s => s.Id > 100 && s.Name.Contains("1"); //这里的lambda实际上是一个表达式目录树,是一个二叉树的数据结构,注意只有一行代码才可以,多行就不行 Expression<Func<Student, bool>> predicate= s => s.Id > 100 && s.Name.Contains("1");
匿名类
#region 3.0出了个匿名类 { Console.WriteLine("*****************匿名类**************"); Student student = new Student() { Id = 1, Name = "Richard", Age = 25, ClassId = 2 }; student.Study(); //匿名类 object model = new//3.0 { Id = 2, Name = "undefined", Age = 25, ClassId = 2, Teacher = "Richard" }; //无法访问属性值,下面代码是报错的。object中肯定有Id/Name,因为C#是强类型语言,编译器不认可,所以没法这样写 //Console.WriteLine(model.Id); //,; //Console.WriteLine(model.Name); //dynamic避开编译器检查 (4.0) //(动态类型),可以避开编译器的检查,只有在实际运行的时候才会检查是否正确 dynamic dModel = new// { Id = 2, Name = "undefined", Age = 25, ClassId = 2 }; Console.WriteLine(dModel.Id); Console.WriteLine(dModel.Name); // Console.WriteLine(dModel.Js);// 会报异常,也只是在运行这段代码的时候报异常,而不是在编译阶段 //var 语法糖 Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); var model1 = new //不能声明方法 { Id = 2, Name = "undefined", Age = 25, ClassId = 2, Teacher = "Richard" }; //注意,匿名生成的模型类只能读取,不能赋值。 Console.WriteLine(model1.Id); Console.WriteLine(model1.Name); //Console.WriteLine(model1.jk); } #endregion