Lambda表达式学习(1)
项目里面需要经常对一系列同类型集合进行操作 , 如对集合进行增加元素 , 删除集合的指定索引的元素等等.我们可以使用ArrayList来进行. 如
- ArrayList stringArrayList = new ArrayList();
- stringArrayList. Add("大家好");
- stringArrayList. Add("你们好");
- stringArrayList. Add("同志们好");
- string str1 = (string)stringArrayList[];//取出一个元素后 , 需要转换一次类型才可以
或者是
- ArrayList intArrayList = new ArrayList();
- intArrayList. Add();
- intArrayList. Add();
- intArrayList. Add();
- int int1 = (int)intArrayList[];//取出一个元素后 , 需要转换一次类型才可以
但是ArrayList中每个元素的类型都是Object(stringArrayList[0]的类型是Object) , 这意味着我们每一次的操作 , 其实都进行了隐式的类型转换 , 加入资料是把普通类型转换成Object类型 , 取出资料是把Object类型转换成普通类型.
于是我在想象 , 如果有一种数组类型 , 在定义的时候 , 可以给出每个元素具体的类型 , 并且在赋值或者取值的时候 , 就是完全按照这个类型进行操作该多好.
在. net2. 0里面 , 我找到了List这个类型. List是一个泛型 , 我们看看List的使用
- 代码
- List<string> stringArrayList = new List<string>();
- stringArrayList. Add("大家好");
- string str1 = stringArrayList[];//直接赋值成功!因为取出来的就是string
- //或者
- List<int> intArrayList = new List<int>();
- intArrayList. Add();
- int int1 = intArrayList[];//直接赋值成功!因为取出来的就是int
大家可以看出 , List在实例化的时候就需要定义一个类型 , 也就是尖括号中间的东西 , 在增加元素 , 或者获取元素的时候 , 操作的都是最开始定义的那种类型. List便是传说中的泛型类型.
泛型可以用在方法上 , 也可以用在类上. 如果看到某个方法或者类后面带有尖括号的 , 那么这个肯定就是泛型了.
现在 , 我找到了能够有效存储我要操作的集合类型 , 那么我们要解决一些操作了.
我需要对集合进行一个连接输出(把所有的元素连接在一起 , 每个元素之间使用<BR>来分割) , 还需要知道所有元素的总长度. 显然 , 光一个List类型是解决不了问题的. 于是我自己定义了一个自己的泛型类型
- 代码
- /// <summary>
- /// 这是一个泛型类 , 类名后面接着一个尖括号里面的那个T, 是我们自己定义的 , 如果你高兴 , 你可以定义w , y , z , WC都没有问题!
- /// 这个T表示说我们在实例化类的时候 , 需要告诉类 , 我们是用哪一种类型来进行操作.
- /// </summary>
- /// <typeparam name = "T"></typeparam>
- public class MyList<T>
- {
- public List<T> _List { get; set; }
- public MyList()
- {
- this. _List = new List<T>();
- }
- /// <summary>
- /// 用来连接所有元素用
- /// </summary>
- /// <returns>连接后的字符串</returns>
- public string JoinOut()
- {
- StringBuilder stbTemp = new StringBuilder();
- foreach (var item in _List)
- {
- stbTemp. Append(item);
- stbTemp. Append("<BR>");
- }
- return stbTemp. ToString();
- }
- /// <summary>
- /// 所有元素的长度
- /// </summary>
- /// <returns>元素的整体长度</returns>
- public int AllLen()
- {
- StringBuilder stbTemp = new StringBuilder();
- foreach (var item in _List)
- {
- stbTemp. Append(item);
- }
- return stbTemp. Length;
- }
- }
但是如果我在求元素长度的时候 , 要求如果是stirng则返回所有元素的长度 , 而是int的时候 , 则返回所有元素的和. 于是我重写了AllLen方法
- 代码
- public int AllLen()
- {
- //StringBuilder stbTemp = new StringBuilder();
- //foreach (var item in _List)
- //{
- // stbTemp. Append(item);
- //}
- //return stbTemp. Length;
- StringBuilder stbTemp = new StringBuilder();
- var type = typeof(T);
- if (type = = typeof(string))
- {
- foreach (var item in _List)
- {
- stbTemp. Append(item);
- stbTemp. Append("<BR>");
- }
- return stbTemp. Length;
- }
- if (type = = typeof(int))
- {
- int intSum = ;
- foreach (var item in _List)
- {
- intSum + = int. Parse(item. ToString());
- }
- return stbTemp. Length;
- }
- /* 这里可能还需要根据不同的类型进行不同的处理
- 32 */
- return ;
- }
我在整个项目中 , 会负责编写公用类库. 我不知道其他前台编码人员需要什么样子的操作. 并且前台编码人员会各处一些稀奇古怪的需求我 , 要我实现 , 如他想接受一系列的bool类型 , 然后判断所有结果为True的数量 , 或者传入一系列的日期 , 判断所有星期一的日期有多少个. . . 等等. 我比较懒 , 并且我非常不愿意去修改我已经写好的类库. 所以我又对Allen进行了一次修改.
- 代码
- //写一个委托 , 谁愿意做什么操作就自己写去 , 哥不管了!
- public delegate int delegateAllLen<T>(List<T> list);
- //写一个委托 , 谁愿意做什么操作就自己写去 , 哥不管了!
- public delegateAllLen<T> FuncAllLen { get; set; }
- public int AllLen()
- {
- if (FuncAllLen ! = null)
- {
- return FuncAllLen(_List);
- }
- return ;
- }
我告诉前台编码人员 , 你们想做什么就先去实现委托FuncAllLen. 然后调用AllLen方法.
- 代码
- /// <summary>
- /// 委托的实现
- /// </summary>
- /// <param name = "bln"></param>
- /// <returns></returns>
- public int Temp(List<bool> bln)
- {
- int i = ;
- foreach (var item in bln)
- {
- if (item) i++;
- }
- return i;
- }
- public void Main()
- {
- var list = new MyList<bool>();
- list. _List. Add(true);
- list. _List. Add(false);
- list. _List. Add(true);
- ///实现委托
- list. FuncAllLen + = Temp;
- MessageBox. Show(list. AllLen(). ToString());
- }
现在我就轻松多了 , 可以去睡大觉了!所有的具体操作 , 前台编码人员自己去实现FuncAllLen 这个委托去!我全部不管了!哈哈哈!
不过这样写可能还是有有点难以理解. 一会定义一个delegate int delegateAllLen<T>(List<T> list);一会又是delegateAllLen<T> FuncAllLen { get; set; } , 都不知道那个是那个. . . .
于是我采用C#3. 5中委托的写法
- 代码
- /*
- 2 public delegate int delegateAllLen<T>(List<T> list);
- 3 public delegateAllLen<T> FuncAllLen { get; set; }
- 4 以上这两句 , 可以简写成下面的一句!
- 5 */
- public Func<List<T> , int> FuncAllLen { get; set; }
调用的方法和以前一样 , 可是编码人员告诉我:这样你方便了 , 我们可就麻烦了 , 每次都要记得在使用AllLen方法的时候 , 都要先把委托实现了. 特别是新来的人 , 总是记不住.
正好 , 最近我在学习Linq , c#3. 5中推出了拉姆达表达式 , 可以让委托更简单的实现!于是我最后一次重写AllLen方法
- 代码
- //我要使用最先进 , 最流行的拉姆达表达式!所以下面的这行委托我不需要了!哈哈哈哈
- //public Func<List<T> , int> FuncAllLen { get; set; }
- //其实我把上面的委托定义放到函数里面当参数了. . . .
- public int AllLen(Func<List<T> , int> FuncAllLen)
- {
- if (FuncAllLen ! = null)
- {
- return FuncAllLen(_List);
- }
- return ;
- }
最后我们看看调用的方法
- 代码
- public void Main()
- {
- var list = new MyList<bool>();
- list. _List. Add(true);
- list. _List. Add(false);
- list. _List. Add(true);
- //传说中的拉姆达表达式出现了!!!!!!
- int intRef = list. AllLen(
- PList = >
- {
- int i = ;
- foreach (var item in PList)
- {
- if (item) i++;
- }
- return i;
- });
- }
具体我们来看看拉姆达表达式的用法!
拉姆达表达式由三个部分组成 , = >是拉姆达中固定的符号 , 必须出现!
= >左边的表达式是一个参数列表 , 是一组没有类型的字符(字符怎么写随意!只要符合命名规范就好了) , 每个字符表示一个参数 , 每个参数之间使用逗号分割.
如:
如果有三个参数 , 则表达式为(A , B , C) , 或者是(P1 , P2 , P3) ,
= >右边的是具体要实现的代码段 , 代码段里面可以使用参数列表中的参数进行各种运算.
如:
{return P1+P2+p3;}
合起来就是 (P1 , P2 , P3) = >{return P1+P2+P3;}
如果参数只有一个 , 那么省去小括号:P1 = >{return P1+10;}
如果具体的实现代码只有一句返回语句 , 则可以简写成 P1 = >P1+10;
一定要注意 , 拉姆达表达式只是一个委托的定义而已 , 当程序运行到拉姆达表达式的时候 , 拉姆达表达式里面的语句是不会被立刻执行的 , 很多人在初学拉姆达或者委托的时候都会犯这种错误.如:
- 代码
- public void Main()
- {
- var intSumTemp = Sum((tempInt) = > { return tempInt + ; });
- }
- public int Sum(Func<int , int> func)
- {
- var int1 = ;
- int1+ = ;
- var intTemp = func(int1);
- return intTemp * intTemp;
- }
上面的intSumTemp的结果是121.
运行的顺序是:首先调用Sum方法而不会去执行拉姆达表达式.
然后得到int1 = 10的结果(5+5) ,
接着需要运行func了 , 并且知道func的参数值是int1 , 即10.
那么func是通过拉姆达表达式定义的 , 所以这个时候 , 我们把10传入拉姆大表达式中 , 进行运算得到11(10+1)
方法最后是一个平方操作. 结果为121(11*11)
知道拉姆达的写法 , 和使用的方法 , 那么我们在什么情况下可以使用拉姆达表达式能?
当我们在使用一个方法 , 方法的参数是Func , 或Action , 那么就可以使用拉姆达表达式了!
我们拿linq里面的方法举例!
- public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source , Func<TSource , bool> predicate);
- 可写成 var temp = _List. Where(P = >{return true;});
- public static int Sum<TSource>(this IEnumerable<TSource> source , Func<TSource , int> selector);
- 可写成 var temp = _List. Sum(P = >P. count);
Lambda表达式学习(1)的更多相关文章
- C# Lambda 表达式学习之(三):动态构建类似于 c => c.Age == null || c.Age > 18 的表达式
可能你还感兴趣: 1. C# Lambda 表达式学习之(一):得到一个类的字段(Field)或属性(Property)名,强类型得到 2. C# Lambda 表达式学习之(二):LambdaExp ...
- C# Lambda 表达式学习之(四):动态构建类似于 c => c.Age == 2 || c.Age == 5 || c => c.Age == 17 等等一个或多个 OrElse 的表达式
可能你还感兴趣: 1. C# Lambda 表达式学习之(一):得到一个类的字段(Field)或属性(Property)名,强类型得到 2. C# Lambda 表达式学习之(二):LambdaExp ...
- java lambda表达式学习笔记
lambda是函数式编程(FP,functional program),在java8中引入,而C#很早之前就有了.在java中lambda表达式是'->',在C#中是‘=>’. 杜甫说:射 ...
- java 8 中lambda表达式学习
转自 http://blog.csdn.net/renfufei/article/details/24600507 http://www.jdon.com/idea/java/10-example-o ...
- C# Lambda表达式学习笔记
本笔记摘抄自:https://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html,记录一下学习过程以备后续查用. 一.Lambda ...
- Lambda 表达式 学习
最近几天在学习Lambda,给我的理解就是一个匿名函数的升级版,代码极大可能的简洁了很多,不需要像以前一样必须使用众多的代码才能实现相关功能. 慢慢积累学习,将Java 8的相关知识进行一个学习. 用 ...
- Python中lambda表达式学习
lambda只是一个表达式,函数体比def简单很多. lambda的主体是一个表达式,而不是一个代码块.仅仅能在lambda表达式中封装有限的逻辑进去. lambda表达式是起到一个函数速写的作用.允 ...
- C#Lambda表达式学习日记
Lambda表达式只是用更简单的方式来写匿名方法,彻底简化了对.NET委托类型的使用. 现在,如果我们要使用泛型 List<> 的 FindAll() 方法,当你从一个集合去提取子集时,可 ...
- C++11 lambda表达式学习
lambda表达式是函数式编程的基础.咱对于函数式编程也没有足够的理解,因此这里不敢胡言乱语,有兴趣的可以自己查找相关资料看下.这里只是介绍C++11中的lambda表达式自己的认识.这里有参考文档h ...
- python第l六天,lambda表达式学习,涉及filter及Map。
在python中lambda表达式可以作为匿名函数来使用,举一个简单的栗子: 以前我们写两个数相加的函数需要 #以前我们写两个数相加的函数,需要这样写 >>> def sum(x,y ...
随机推荐
- Codeforces 1097 Alex and a TV Show
传送门 除了操作 \(3\) 都可以 \(bitset\) 现在要维护 \[C_i=\sum_{gcd(j,k)=i}A_jB_k\] 类比 \(FWT\),只要求出 \(A'_i=\sum_{i|d ...
- Django之WSGI浅谈
一.什么是Web框架 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统. 浏览器与服务器之间发起HTTP请求: 1.浏览器发送一 ...
- angualrJs实现图片上传功能
整体逻辑:service提供FileReader函数,directive提供点击事件的绑定和监听,controller用来修改html上的ng-src属性值 1.HTML <input type ...
- 爬虫必备—Scrapy
一.Scrapy简介 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了页面抓取 (更确切来说, 网络抓取 ...
- A Complete Tutorial to Learn Data Science with Python from Scratch
A Complete Tutorial to Learn Data Science with Python from Scratch Introduction It happened few year ...
- Batch Norm、Layer Norm、Weight Norm与SELU
加速网络收敛——BN.LN.WN与selu 自Batch Norm出现之后,Layer Norm和Weight Norm作为Batch Norm的变体相继出现.最近又出来一个很”简单”的激活函数Sel ...
- Android属性动画的监听事件
整体很简单,直接上代码吧.activity_main.xml: <?xml version="1.0" encoding="utf-8"?> < ...
- 百度网盘下载器 PanDownload v2.0
PanDownload是一款坚持以用户体验为中心,畅快淋漓的下载为理念而打造的下载工具. 从2017年2月9日首个版本推出,时至今日已经一年七个月了,首先感谢大家一直以来的支持与建议,促使着我不断地对 ...
- 网络 TCP三次握手及滑动窗口
三次握手客户端向服务器发出触发请求syn=1:因为这时还没有得到服务器的回应,所以ack=0服务器接收到客户端的触发请求,回复ack=1,表示已经接收到客户端的请求:同时服务器也向客户端发出触发请求, ...
- create alter rename desc select update delete insert
conn scott/root;create table student (id number(3), name varchar2(10), sex char(2), sno number(3));a ...