Lambda表达式学习

Lambda表达式学习

  项目里面需要经常对一系列同类型集合进行操作 ,  如对集合进行增加元素 ,  删除集合的指定索引的元素等等.
  我们可以使用ArrayList来进行.

 

1 ArrayList stringArrayList= new ArrayList();
2 stringArrayList. Add("大家好");
3 stringArrayList. Add("你们好");
4 stringArrayList. Add("同志们好");
5 string str1 = (string)stringArrayList[0];//取出一个元素后 , 需要转换一次类型才可以

 

 或者是

 

1 ArrayList intArrayList= new ArrayList();
2 intArrayList. Add(6);
3 intArrayList. Add(8);
4 intArrayList. Add(66);
5 int int1 = (int)intArrayList[0];//取出一个元素后 , 需要转换一次类型才可以

 

  但是ArrayList中每个元素的类型都是Object(stringArrayList[0]的类型是Object) , 这意味着我们每一次的操作 , 其实都进行了隐式的类型转换 , 加入资料是把普通类型转换成Object类型 , 取出资料是把Object类型转换成普通类型.
  于是我在想象 , 如果有一种数组类型 , 在定义的时候 , 可以给出每个元素具体的类型 , 并且在赋值或者取值的时候 , 就是完全按照这个类型进行操作该多好.
  在. net2. 0里面 , 我找到了List这个类型. List是一个泛型 , 我们看看List的使用

 

代码

1 List<string> stringArrayList =  new List<string>();
2 stringArrayList. Add("大家好");
3 string str1  =  stringArrayList[0];//直接赋值成功!因为取出来的就是string
4 //或者
5 List<int> intArrayList  =  new List<int>();
6 intArrayList. Add(8);
7 int int1 = intArrayList[0];//直接赋值成功!因为取出来的就是int

 

 

  大家可以看出 , List在实例化的时候就需要定义一个类型 , 也就是尖括号中间的东西 , 在增加元素 , 或者获取元素的时候 , 操作的都是最开始定义的那种类型. List便是传说中的泛型类型.
  泛型可以用在方法上 , 也可以用在类上. 如果看到某个方法或者类后面带有尖括号的 , 那么这个肯定就是泛型了.

  现在 , 我找到了能够有效存储我要操作的集合类型 , 那么我们要解决一些操作了.
  我需要对集合进行一个连接输出(把所有的元素连接在一起 , 每个元素之间使用<BR>来分割) , 还需要知道所有元素的总长度. 显然 , 光一个List类型是解决不了问题的. 于是我自己定义了一个自己的泛型类型

 

代码

 1 /// <summary>
 2     /// 这是一个泛型类 , 类名后面接着一个尖括号里面的那个t , 是我们自己定义的 , 如果你高兴 , 你可以定义w , y , z , WC都没有问题!
 3     /// 这个T表示说我们在实例化类的时候 , 需要告诉类 , 我们是用哪一种类型来进行操作.
 4     /// </summary>
 5     /// <typeparam name = "T"></typeparam>
 6     public class MyList<T>
 7     {
 8         public List<T> _List { getset; }
 9         public MyList()
10         {
11             this. _List  =  new List<T>();
12         }
13         /// <summary>
14         /// 用来连接所有元素用
15         /// </summary>
16         /// <returns>连接后的字符串</returns>
17         public string JoinOut()
18         {
19             StringBuilder stbTemp =  new StringBuilder();
20             foreach (var item in _List)
21             {
22                 stbTemp.Append(item);
23                 stbTemp.Append("<BR>");
24             }
25             return stbTemp. ToString();
26         }
27         /// <summary>
28         /// 所有元素的长度
29         /// </summary>
30         /// <returns>元素的整体长度</returns>
31         public int AllLen()
32         {
33             StringBuilder stbTemp =  new StringBuilder();
34             foreach (var item in _List)
35             {
36                 stbTemp.Append(item);
37             }
38             return stbTemp. Length;
39         }
40 
41     }

 

但是如果我在求元素长度的时候 , 要求如果是stirng则返回所有元素的长度 , 而是int的时候 , 则返回所有元素的和. 于是我重写了AllLen方法

 

代码

 1     public int AllLen()
 2         {
 3             //StringBuilder stbTemp  =  new StringBuilder();
 4             //foreach (var item in _List)
 5             //{
 6             //    stbTemp.Append(item);
 7             //}
 8             //return stbTemp.Length;
 9 
10             StringBuilder stbTemp =  new StringBuilder();
11             var type =  typeof(T);
12             if (type =  =  typeof(string))
13             {
14                 foreach (var item in _List)
15                 {
16                     stbTemp.Append(item);
17                     stbTemp.Append("<BR>");
18                 }
19                 return stbTemp. Length;
20             }
21             if (type =  =  typeof(int))
22             {
23                 int intSum =  0;
24                 foreach (var item in _List)
25                 {
26                     intSum +=  int. Parse(item.ToString());
27                 }
28                 return stbTemp. Length;
29             }
30 
31             /*  这里可能还需要根据不同的类型进行不同的处理
32              */
33             return 0;
34         }

 

 我在整个项目中 , 会负责编写公用类库. 我不知道其他前台编码人员需要什么样子的操作. 并且前台编码人员会各处一些稀奇古怪的需求我 , 要我实现 , 如他想接受一系列的bool类型 , 然后判断所有结果为True的数量 , 或者传入一系列的日期 , 判断所有星期一的日期有多少个. . . 等等. 我比较懒 , 并且我非常不愿意去修改我已经写好的类库. 所以我又对Allen进行了一次修改.

 

代码

 1     //写一个委托 , 谁愿意做什么操作就自己写去 , 哥不管了!
 2     public delegate int delegateAllLen<T>(List<T> list);
 3         //写一个委托 , 谁愿意做什么操作就自己写去 , 哥不管了!
 4         public delegateAllLen<T> FuncAllLen { getset; }
 5         public int AllLen()
 6         {
 7             if (FuncAllLen !=  null)
 8             {
 9                 return FuncAllLen(_List);
10             }
11             return 0;
12         }

我告诉前台编码人员 , 你们想做什么就先去实现委托FuncAllLen.然后调用AllLen方法.

 

代码

 1     /// <summary>
 2         /// 委托的实现
 3         /// </summary>
 4         /// <param name = "bln"></param>
 5         /// <returns></returns>
 6         public int Temp(List<bool> bln)
 7         {
 8             int i  =  0;
 9             foreach (var item in bln)
10             {
11                 if (item) i++;
12             }
13             return i;
14         }
15 
16         public void Main()
17         {
18             var list =  new MyList<bool>();
19 
20             list._List. Add(true);
21             list._List. Add(false);
22             list._List. Add(true);
23             ///实现委托
24             list.FuncAllLen + =  Temp;
25             MessageBox.Show(list. AllLen(). ToString());
26         }
27 
28 

现在我就轻松多了 , 可以去睡大觉了!所有的具体操作 , 前台编码人员自己去实现FuncAllLen 这个委托去!我全部不管了!哈哈哈!
不过这样写可能还是有有点难以理解. 一会定义一个delegate int delegateAllLen<T>(List<T> list);一会又是delegateAllLen<T>FuncAllLen { get; set; } , 都不知道那个是那个. . . .
于是我采用C#3. 5中委托的写法

 

代码

1        /*
2         public delegate int delegateAllLen<T>(List<T> list);
3         public delegateAllLen<T> FuncAllLen { get; set; }
4         以上这两句 , 可以简写成下面的一句!
5          */
6         public Func<List<T>,  int> FuncAllLen { getset; }

调用的方法和以前一样 , 可是编码人员告诉我:这样你方便了 , 我们可就麻烦了 , 每次都要记得在使用AllLen方法的时候 , 都要先把委托实现了. 特别是新来的人 , 总是记不住.
正好 , 最近我在学习Linq , c#3. 5中推出了拉姆达表达式 , 可以让委托更简单的实现!于是我最后一次重写AllLen方法

 

代码

 1     //我要使用最先进 , 最流行的拉姆达表达式!所以下面的这行委托我不需要了!哈哈哈哈
 2     //public Func<List<T>,  int> FuncAllLen { get; set; }
 3 
 4         //其实我把上面的委托定义放到函数里面当参数了. . . .
 5         public int AllLen(Func<List<T> , int >FuncAllLen)
 6         {
 7             if (FuncAllLen !=  null)
 8             {
 9                 return FuncAllLen(_List);
10             }
11             return 0;
12         }

 

最后我们看看调用的方法

代码

 1 public void Main()
 2         {
 3             var list =  new MyList<bool>();
 4 
 5             list._List. Add(true);
 6             list._List. Add(false);
 7             list._List. Add(true);
 8         //传说中的拉姆达表达式出现了!!!!!!
 9             int intRef =  list. AllLen(
10                 PList = >
11                 {
12                     int i  =  0;
13                     foreach (var item in PList)
14                     {
15                         if (item) i++;
16                     }
17                     return i;
18                 });
19         }

 

 

具体我们来看看拉姆达表达式的用法!
拉姆达表达式由三个部分组成= >是拉姆达中固定的符号 , 必须出现!
 
= >左边的表达式是一个参数列表 , 是一组没有类型的字符(字符怎么写随意!只要符合命名规范就好了) , 每个字符表示一个参数 , 每个参数之间使用逗号分割.
:
 
如果有三个参数 , 则表达式为(A , B , C) , 或者是(P1 , P2 , P3) ,
 
= >右边的是具体要实现的代码段 , 代码段里面可以使用参数列表中的参数进行各种运算.
:
{return P1+P2+p3;}
合起来就是 (P1 , P2 , P3) = >{returnP1+P2+P3;}
如果参数只有一个 , 那么省去小括号:P1 = >{returnP1+10;}
如果具体的实现代码只有一句返回语句 , 则可以简写成 P1 = >P1+10;

一定要注意 , 拉姆达表达式只是一个委托的定义而已 , 当程序运行到拉姆达表达式的时候 , 拉姆达表达式里面的语句是不会被立刻执行的 , 很多人在初学拉姆达或者委托的时候都会犯这种错误.
:

 

代码

 1      public void Main()
 2         {
 3              var intSumTemp =  Sum((tempInt)  = > { return tempInt + 1; });
 4         }
 5 
 6         public int Sum(Func<int ,  int> func)
 7         {
 8         var int1= 5;
 9         int1+= 5;
10             var intTemp =  func(int1);
11             return intTemp * intTemp;
12         }

 

 

上面的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>(thisIEnumerable<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);

拉姆达表达式学习(2)

. net3. 5里面 , 委托的定义和实现被大大的简化了!使用关键字FuncAction就可以定义一个委托 , 使用拉姆达表达式就可以实现一个具体的委托.
Func
关键字是用来定义一个有返回值的委托 , 它一共有五个重载 , 我们介绍其中的三个
1 public delegate TResult Func<TResult>();
 
这表示一个没有参数 , 只有一个返回值的委托 , 返回值的类型就是TResult(泛型)

 

代码

 1  public class test
 2     {
 3         /// <summary>
 4         /// 定义一个委托
 5         /// </summary>
 6         public Func<string> _GetName;
 7         /// <summary>
 8         /// 一个普通的没有参数 , 有返回值的方法
 9         /// </summary>
10         /// <returns></returns>
11         public string GetName()
12         {
13             return "张三";
14         }
15         public void Main()
16         {
17             //3. 5以前的委托的实现 , 直接赋值
18             _GetName =  GetName;
19 
20             //拉姆达表达式的实现方法
21             _GetName =  (
22                 ()          //因为这个委托没参数 , 所以参数列表没有东西
23                     = >      //拉姆达表达式的符号
24                 {           //大括号的代码段表示具体的委托的实现
25                     return "还是张三";
26                 });
27             //拉姆达表达式的简写 , 如果委托的实现代码段中只有一句return 则可以省略代码段最外面的大括号 , return关键字
28             _GetName =  ()  = > "总是张三";
29             //调用
30             string MyName =  _GetName();
31         }
32     }

 

2 public delegate TResult Func<T ,  TResult>(T arg);
 这表示有且仅有一个参数 , 并且有返回值的委托.

 

代码

 1  public class test
 2     {
 3         /// <summary>
 4         /// 定义一个委托 , 有一个参数和一个返回值
 5         /// </summary>
 6         public Func<string ,  string> _GetName;
 7         /// <summary>
 8         /// 有一个参数的方法
 9         /// </summary>
10         /// <param name = "strName">这是一个参数!</param>
11         /// <returns>这是一个返回值</returns>
12         public string GetName(string strName)
13         {
14             return strName;
15         }
16         public void Main()
17         {
18             //3. 5以前的委托的实现 , 直接赋值
19             _GetName =  GetName;
20 
21             //拉姆达表达式的实现方法
22             _GetName =  (
23                 (S)          //有一个参数!所以参数列表里面有一个东西 , 这个东西随大家高兴叫个阿猫阿狗都行!只要符合规范
24                     = >      //拉姆达表达式的符号
25                 {           //大括号的代码段表示具体的委托的实现
26                     return "还是" + S;
27                 });
28             //拉姆达表达式的简写 , 如果委托的实现代码段中只有一句return 则可以省略代码段最外面的大括号 , return关键字
29             _GetName =  (abc)  = > "总是" + abc;
30             //调用
31             string MyName =  _GetName("张三");
32         }
33     }

 

3 public delegate TResult Func<T1 ,  T2 ,  TResult>(T1 arg1 ,  T2 arg2);
 这表示有且仅有两个参数 , 并且有返回值的委托.

 

代码

 1  public class test
 2     {
 3         /// <summary>
 4         /// 定义一个委托 , 有一个参数和一个返回值
 5         /// </summary>
 6         public Func<string ,  int ,  string> _GetName;
 7         /// <summary>
 8         /// 这是一个有两个参数的方法 , 方法的参数类型的顺序必须和委托的参数类型顺序一致
 9         /// </summary>
10         /// <param name = "strName">第一个是字符类型</param>
11         /// <param name = "intAGE">第二个是整形 , 请不要颠倒类型!</param>
12         /// <returns>返回一个字符串 , 对应委托的最后一个参数</returns>
13         public string GetName(string strName ,  int intAGE)
14         {
15             return string. Format("{0}的年龄是{1}" ,  strName ,  intAGE);
16         }
17         public void Main()
18         {
19             //3. 5以前的委托的实现 , 直接赋值
20             _GetName =  GetName;
21 
22             //拉姆达表达式的实现方法
23             _GetName =  (
24                 (S,  W)          //有一个参数!所以参数列表里面有一个东西 , 这个东西随大家高兴叫个阿猫阿狗都行!只要符合规范
25                     = >      //拉姆达表达式的符号
26                 {           //大括号的代码段表示具体的委托的实现
27                     return string. Format("{0}的年龄是{1}" ,  S ,  W);
28                 });
29             //拉姆达表达式的简写 , 如果委托的实现代码段中只有一句return 则可以省略代码段最外面的大括号 , return关键字
30             _GetName =  (abc ,  efd)  = > string. Format("{0}的年龄是{1}" ,  abc ,  efd);
31             //调用
32             string MyName =  _GetName("张三" ,  33);
33         }
34     }

 

Action关键字用来定义一个没有返回值的方法 , 它有一个非泛型方法 , 和四个泛型方法 , 一共五种. Actionfunc的区别就在于一个没有返回值 , 一个有返回值!其他的都一样!就好像VBsubfunction一样!
1 public delegate void Action();
没有参数也没有返回值

 

代码

 1 public class test
 2     {
 3         /// <summary>
 4         /// 定义一个委托 , 没有返回值也没有参数
 5         /// </summary>
 6         public Action _GetName;
 7 
 8         public void GetName()
 9         {
10             System.Windows. Forms. MessageBox. Show("没有参数也没有返回值 , 我只要自己显示了!");
11         }
12         public void Main()
13         {
14             //3. 5以前的委托的实现 , 直接赋值
15             _GetName =  GetName;
16 
17             //拉姆达表达式的实现方法
18             _GetName =  (
19                 ()
20                     = >      //拉姆达表达式的符号
21                 {           //大括号的代码段表示具体的委托的实现
22                     System.Windows. Forms. MessageBox. Show("没有参数也没有返回值 , 我只要自己显示了!");
23                 });
24             //因为action没有返回值 , 所以下面的简写方式是错误的
25             //_GetName =  ()  = > System. Windows. Forms. MessageBox. Show("没有参数也没有返回值 , 我只要自己显示了!"); 
26             //调用
27             _GetName();
28         }
29     }

2  public delegate voidAction<T>(T obj);
有一个参数但没有返回值

 

 

代码

 1 public class test
 2     {
 3         /// <summary>
 4         /// 定义一个委托 , 没有返回值也没有参数
 5         /// </summary>
 6         public Action<bool> _GetName;
 7 
 8         public void GetName(bool blnShow)
 9         {
10             if (blnShow)
11             {
12                 System.Windows. Forms. MessageBox. Show("要我显示就显示 , 多没面子");
13             }
14             else
15             {
16                 System.Windows. Forms. MessageBox. Show("不要我显示 , 我偏要显示");
17             }
18         }
19         public void Main()
20         {
21             //3. 5以前的委托的实现 , 直接赋值
22             _GetName =  GetName;
23 
24             //拉姆达表达式的实现方法
25             _GetName =  (
26                 (b)
27                     = >      //拉姆达表达式的符号
28                 {           //大括号的代码段表示具体的委托的实现
29                     if (b)
30                     {
31                         System.Windows. Forms. MessageBox. Show("要我显示就显示 , 多没面子");
32                     }
33                     else
34                     {
35                         System.Windows. Forms. MessageBox. Show("不要我显示 , 我偏要显示");
36                     }
37                 });
38 
39             _GetName(true);
40         }
41     }

 

CH341A编程器是一款广泛应用的通用编程设备,尤其在电子工程和嵌入式系统开发领域中,它被用来烧录各种类型的微控制器、存储器和其他IC芯片。这款编程器的最新版本为1.3,它的一个显著特点是增加了对25Q256等32M芯片的支持。 25Q256是一种串行EEPROM(电可擦可编程只读存储器)芯片,通常用于存储程序代码、配置数据或其他非易失性信息。32M在这里指的是存储容量,即该芯片可以存储32兆位(Mbit)的数据,换算成字节数就是4MB。这种大容量的存储器在许多嵌入式系统中都有应用,例如汽车电子、工业控制、消费电子设备等。 CH341A编程器的1.3版更新,意味着它可以与更多的芯片型号兼容,特别是针对32M容量的芯片进行了优化,提高了编程效率和稳定性。26系列芯片通常指的是Microchip公司的25系列SPI(串行外围接口)EEPROM产品线,这些芯片广泛应用于各种需要小体积、低功耗和非易失性存储的应用场景。 全功能版的CH341A编程器不仅支持25Q256,还支持其他大容量芯片,这意味着它具有广泛的兼容性,能够满足不同项目的需求。这包括但不限于微控制器、EPROM、EEPROM、闪存、逻辑门电路等多种类型芯片的编程。 使用CH341A编程器进行编程操作时,首先需要将设备通过USB连接到计算机,然后安装相应的驱动程序和编程软件。在本例中,压缩包中的"CH341A_1.30"很可能是编程软件的安装程序。安装后,用户可以通过软件界面选择需要编程的芯片类型,加载待烧录的固件或数据,然后执行编程操作。编程过程中需要注意的是,确保正确设置芯片的电压、时钟频率等参数,以防止损坏芯片。 CH341A编程器1.3版是面向电子爱好者和专业工程师的一款实用工具,其强大的兼容性和易用性使其在众多编程器中脱颖而出。对于需要处理25Q256等32M芯片的项目,或者26系列芯片的编程工作,CH341A编程器是理想的选择。通过持续的软件更新和升级,它保持了与现代电子技术同步,确保用户能方便地对各种芯片进行编程和调试。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值