lambda,linq
一:什么是Lambda表达式
lambda表达式是实例化委托的一个参数,就是一个方法,具体实现如下:
{
//.NetFramework 1.0-1.1的时候这样应用
NoReturnNoPara method = new NoReturnNoPara(DoNothing);
method.Invoke(); //.NetFramwork2.0 匿名方法出现,delegate关键字,可以访问局部变量
int i = ;
NoReturnWithPara method1 = new NoReturnWithPara(delegate (int id, int age)
{
Console.WriteLine(i);
Console.WriteLine($"{id} 今年{age}岁了!");
});
method1.Invoke(, ); //.NetFramwork3.0 把delegate关键字去掉,然后增加了一个箭头goes to
//lambda表达式:参数列表=>方法体
NoReturnWithPara method2 = new NoReturnWithPara((int id, int age) =>
{
Console.WriteLine(i);
Console.WriteLine($"{id} 今年{age}岁了!");
});
method2.Invoke(, ); NoReturnWithPara method3 = new NoReturnWithPara((id, age) =>
{ //省略参数类型,但是编译器可以根据委托推断出类型,是语法糖
Console.WriteLine(i);
Console.WriteLine($"{id} 今年{age}岁了!");
});
method3.Invoke(, ); //如果方法体只有一行,可以去掉大括号和分号
NoReturnWithPara method4 = new NoReturnWithPara((id, age) => Console.WriteLine($"{id} 今年{age}岁了!"));
method4.Invoke(, ); //如果方法体只有一行,可以去掉大括号和分号,还可以去掉new NoReturnWithPara,这个也是编译器语法糖
NoReturnWithPara method5 = (id, age) => Console.WriteLine($"{id} 今年{age}岁了!");
method4.Invoke(, ); //下面带有返回值的
Func<int> func0 = () => { return DateTime.Now.Month; };//有一个返回值
Func<int> func1 = () => DateTime.Now.Month; //如果方法体只有一行,去掉大括号分号和return }
使用反编译工具看会产生一个私有sealed类,然后会看到lambda表达式都会生成一个方法名字,然后都会在包括在Sealed类里面
二:匿名类(.netFramwork3.0)
匿名类是.netFramwork3.0出现的,语法是:object object=new{};
下面有几种声明方式:
object model = new//3.0
{
Id = ,
Name = "undefined",
Age = ,
ClassId =
};
// Console.WriteLine(model.Id);//object 编译器不允许 var varModel = new//3.0 编译后是有一个真实的类
{
Id = ,
Name = "undefined",
Age = ,
ClassId =
};
Console.WriteLine(varModel.Id); //编译器可以找到
//varModel.Id = 123;//只能get 没有set
//反射可以找到 //dynamic避开编译器
dynamic dModel = new//4.0
{
Id = ,
Name = "undefined",
Age = ,
ClassId =
}; var s = dModel;
下面说一下var这个类型
var:是一个语法糖,由编译器自动推算出变量的类型,一般配合匿名类型使用,然后如遇到复杂类型,可以用之代替,但使用时,以下几点需要注意:
1:var声明的时候一定要确定类型,比如var dd=null或者var aa; 都是编译不通过的
2:一旦确定类型后是不能修改类型的,比如: var s = "加菲猫";则后面不能修改为:s=122;
三:扩展方法(.netFramwork3.0)
什么是扩展方法?答案则是静态类里面的静态方法,第一个参数类型前面加上this
具体如下:
public static class ExtendMethod
{
public static void Show<T>(this T t)//最好加约束
{ } public static void Sing(this Student student)
{
Console.WriteLine($"{student.Name} Sing a Song");
} /// <summary>
/// null默认是defaultValue,默认是0
/// </summary>
/// <param name="iValue"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static int ToInt(this int? iValue, int defaultValue = )
{
return iValue ?? defaultValue;
} public static bool Than(this int value1, int value2)
{
return value1 > value2;
} /// <summary>
/// 扩展基类型,导致任何子类都有这个方法,而且还可能被覆盖啥的
/// </summary>
/// <param name="iValue"></param>
/// <returns></returns>
public static int Length(this object oValue)
{
return oValue == null ? : oValue.ToString().Length;
} }
然后调用的时候如下:
int? iValue1 = nul
int? iValue = ;
iValue1.ToInt();
iValue1.Length();
s.Length();
.Than();
扩展方法的用途:
1:适合用于一些不经常修改的地方
2:适合组件式开发的扩展(.netcore),定义接口或者类,是按照最小需求,但是开发的时候又经常需要一些方法,就是通过扩展方法,context.Response.WriteAsync
还有中间件的注册
3:扩展一些常见操作
扩展方法缺陷:优先调用类型的实例方法(有隐患),会污染基础类型,一般少为object 或者没有约束的泛型去扩展,扩展基类型,导致任何子类都有这个方法,而且还可能被覆盖啥的
三:linq
linq和lamda的关系:
lambda和linq的关系
lambda:是实例化委托的快捷方式,是一个方法
linq:是基于委托(lambda)的封装,代码重用,逻辑解耦,是一个帮助类库
linq是用泛型,委托,lamda实现的,总的来说:把对数据操作的通用部分完成,把可变的交给委托,使用者只关心可变部分。
我们还是以例子来讲,先初始化一些基础数据
private List<Student> GetStudentList()
{
#region 初始化数据
List<Student> studentList = new List<Student>()
{
new Student()
{
Id=,
Name="赵亮",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="再努力一点",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="王炸",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="疯子科学家",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="灭",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="黑骑士",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="故乡的风",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="晴天",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="旭光",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="oldkwok",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="乐儿",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="暴风轻语",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="一个人的孤单",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="小张",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="阿亮",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="37度",
ClassId=,
Age=
}
,
new Student()
{
Id=,
Name="关耳",
ClassId=,
Age=
}
,
new Student()
{
Id=,
Name="耳机侠",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="Wheat",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="Heaven",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="等待你的微笑",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="畅",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="混无痕",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="37度",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="新的世界",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="Rui",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="帆",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="肩膀",
ClassId=,
Age=
},
new Student()
{
Id=,
Name="孤独的根号三",
ClassId=,
Age=
}
};
#endregion
return studentList;
}
只要实现了IEnumerable这个接口,都是可以使用 where,Count等方法,只要底层是实现IEnumerable的,都是linq to object
linq To object 是.netFramwork3.0的一个非常重大的改变
下面展示一下linq to object 的几种使用方式
#region linq to object Show
{
Console.WriteLine("********************");
var list = from s in studentList
where s.Age <
select s; foreach (var item in list)
{
Console.WriteLine("Name={0} Age={1}", item.Name, item.Age);
}
} {
Console.WriteLine("********************");
var list = studentList.Where<Student>(s => s.Age < )
.Select(s => new
{
IdName = s.Id + s.Name,
ClassName = s.ClassId == ? "高级班" : "其他班"
});
foreach (var item in list)
{
Console.WriteLine("Name={0} Age={1}", item.ClassName, item.IdName);
}
}
{
Console.WriteLine("********************");
var list = from s in studentList
where s.Age <
select new
{
IdName = s.Id + s.Name,
ClassName = s.ClassId == ? "高级班" : "其他班"
}; foreach (var item in list)
{
Console.WriteLine("Name={0} Age={1}", item.ClassName, item.IdName);
}
}
{
Console.WriteLine("********************");
var list = studentList.Where<Student>(s => s.Age < )//条件过滤
.Select(s => new//投影
{
Id = s.Id,
ClassId = s.ClassId,
IdName = s.Id + s.Name,
ClassName = s.ClassId == ? "高级班" : "其他班"
})
.OrderBy(s => s.Id)//排序 .OrderByDescending(s => s.ClassId)//倒排
.Skip()//跳过几条
.Take()//获取几条
;
foreach (var item in list)
{
Console.WriteLine($"Name={item.ClassName} Age={item.IdName}");
}
}
{//group by
Console.WriteLine("********************");
var list = from s in studentList
where s.Age <
group s by s.ClassId into sg
select new
{
key = sg.Key,
maxAge = sg.Max(t => t.Age)
};
foreach (var item in list)
{
Console.WriteLine($"key={item.key} maxAge={item.maxAge}");
}
//group by new {s.ClassId,s.Age}
//group by new {A=s.ClassId>1}
}
{
Console.WriteLine("********************");
var list = studentList.GroupBy(s => s.ClassId).Select(sg => new
{
key = sg.Key,
maxAge = sg.Max(t => t.Age)
});
foreach (var item in list)
{
Console.WriteLine($"key={item.key} maxAge={item.maxAge}");
}
}
List<Class> classList = new List<Class>()
{
new Class()
{
Id=,
ClassName="初级班"
},
new Class()
{
Id=,
ClassName="高级班"
},
new Class()
{
Id=,
ClassName="微信小程序"
},
};
{
var list = from s in studentList
join c in classList on s.ClassId equals c.Id
select new
{
Name = s.Name,
CalssName = c.ClassName
};
foreach (var item in list)
{
Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
}
}
{
var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
{
Name = s.Name,
CalssName = c.ClassName
});
foreach (var item in list)
{
Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
}
}
{//左连接
var list = from s in studentList
join c in classList on s.ClassId equals c.Id
into scList
from sc in scList.DefaultIfEmpty()//
select new
{
Name = s.Name,
CalssName = sc == null ? "无班级" : sc.ClassName//c变sc,为空则用
};
foreach (var item in list)
{
Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
}
Console.WriteLine(list.Count());
}
{
var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
{
Name = s.Name,
CalssName = c.ClassName
}).DefaultIfEmpty();//为空就没有了
foreach (var item in list)
{
Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
}
Console.WriteLine(list.Count());
}
{ }
#endregion
linq to sql 运用的是表达式目录树,这个底层是实现的IQueryable,概念和linq to object是不一样的!
lambda,linq的更多相关文章
- C#3.0新特性:隐式类型、扩展方法、自动实现属性,对象/集合初始值设定、匿名类型、Lambda,Linq,表达式树、可选参数与命名参数
一.隐式类型var 从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型var.隐式类型可以替代任何类型,编译器自动推断类型. 1.var类型的局部变量必须赋予初始值,包括匿名 ...
- sql,lambda,linq语句
实例 Code 查询Student表的所有记录. select * from student Linq: from s in Students select s Lambda: Students.Se ...
- Linq与Lambda,神一般的工作效率
Linq与Lambda,神一般的工作效 通过对linq和lambda的学习,越发感觉linq和lambda的重要性,他们能极大地简化程序,同时提升程序的可读性,大大提升了我们的工作效率,在公司的 ...
- EF删除,查询,Linq查询,Lambda查询,修改链接字符串
(1)//删除操作 public bool delete() { try { a_context = new AEntities(); b1 = new Table_1(); //删除只需要写主键就行 ...
- 第十二节:Lambda、linq、SQL的相爱相杀(1)
一. 谈情怀 Lambda.Linq.SQL伴随着我的开发一年又一年,但它们三者并没有此消彼长,各自占有这一定的比重,起着不可替代的作用. 相信我们最先接触的应该就是SQL了,凡是科班出身的人,大学 ...
- .Net进阶系列(4)-Lambda和linq入门(被替换)
一. Lambda和linq入门 lambda表达式又叫点标记,linq表达式又叫查询表达式,下面有三个简单的案例说明一下二者的基本用法,详细用法会在后续章节中更新. 二. 事例 1. 准备学生信息. ...
- C# lambda 和 Linq
本章节给大家带来的是Lambda 和 Linq 的关系 Lambda : 是实例化委托的一个参数,也就是一个方法 Linq:是基于委托(lambda)的封装,代码重用,逻辑解耦,是一个帮助类库,lin ...
- 感受一下.net中用 lambda与 linq 做数据集过滤的不同
lambda: ids.Add( _hahahacontext .hahahamodel .FirstOrDefault( a => //lambda做过滤 a.name == "张宏 ...
- 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...
随机推荐
- Python数据结构之单链表
Python数据结构之单链表 单链表有后继结点,无前继结点. 以下实现: 创建单链表 打印单链表 获取单链表的长度 判断单链表是否为空 在单链表后插入数据 获取单链表指定位置的数据 获取单链表指定元素 ...
- Equal 路由类
1.Route 原型 class Route { /* 获取请求路径和查询字符串 */ /* 获取模块.控制器.动作名称 */ /* 获取 URI 参数 */ }
- php中连接mysql数据库的第一步操作
<?phperror_reporting(E_ALL ^ E_DEPRECATED);//设置报警级别人$mylink = mysql_connect("localhost" ...
- C++的IO处理中的头文件以及类理解(1)
C++语言不直接处理输入输出,而是通过一簇定义在标准库中的类型来处理IO.这些类型支持从设备读取数据.向设备写入数据的IO操作,设备可以是文件.控制台窗口等,还有一些类型允许内存IO,即,从strin ...
- wxPyhon 的控件(摘抄)
一.静态文本控件 wx.StaticText(parent, id, label, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, n ...
- 剑指offer面试题27:二叉搜索树与双向链表
题目:输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的节点,只能调整树中节点指针的指向. 由于二叉搜索树是有序的,左子结点的值小于根节点的值,右子结点的值大于根节点的值 ...
- 笔记:Zygote和SystemServer进程启动过程
简述 Android设备启动过程中,先是Linux内核加载完,接着Android中的第一个进程init启动,它会启动一些需要开机启动的进程. Zygote就是进程init启动起来的.Android中所 ...
- java数据结构面试问题—快慢指针问题
上次我们学习了环形链表的数据结构,那么接下来我们来一起看看下面的问题, 判断一个单向链表是否是环形链表? 看到这个问题,有人就提出了进行遍历链表,记住第一元素,当我们遍历后元素再次出现则是说明是环形链 ...
- Numpy学习三:数组运算
1.转置 #reshape(shape)函数改变数组形状,shape是一个元组,表示数组的形状 创建一个包含15个元素的一维数组,通过reshape函数调整数组形状为3行5列的二维数组arr = np ...
- python中的进制转换
python中常用的进制转化通常有两种方法: 1.用内置函数hex(),oct(),bin(),对应的数字表示为0x,0o,0b,功能是把十进制数字转化为其他进制 >>> int( ...