第八节:语法总结(2)(匿名类、匿名方法、扩展方法)
一. 匿名类
1. 传统的方式给类赋值,需要先建一个实体类→实例化→赋值,步骤很繁琐,在.Net 3.0时代,微软引入匿名类的概念,简化了代码编写,提高了开发效率。
匿名类的声明语法: var obj=new {字段赋值};
代码如下:
1 // 匿名类(匿名类通过new关键字实现) 2 Console.WriteLine("------------------------------匿名类(匿名类通过new关键字实现)------------------------------"); 3 var test1 = new 4 { 5 id = "1", 6 name = "maru1" 7 }; 8 Console.WriteLine("id为{0},name为{1}", test1.id, test1.name);
运行结果如下:
2. 匿名类的属性都是只读的
1 { 2 // test1.id = "2"; //报错 3 }
3. 匿名类的属性共享机制
A:属性的名称、类型和顺序一致,那么它们共享一个泛型类。
B:属性的名称和顺序一致,但是属性类型不同,那么它们还是共享一个泛型类,只是泛型参数改变了,所以运行时,会生成不同的类。
C:如果数据型名称和类型相同,但顺序不同,那么编译器会重新创建一个匿名类。
代码如下:
{ var test1 = new { id = "1", name = "maru1" }; //1.属性名称、类型和顺序都一致,那么默认共享前一个泛型类 Console.WriteLine("------------------------------1.属性类型和顺序都一致,那么默认共享前一个泛型类------------------------------"); var test2 = new { id = "2", name = "maru2" }; Console.WriteLine(test1.GetType() == test2.GetType()); //2.如果属性名称和顺序一致,但属性类型不同,那么还是共同使用一个泛型类,只是泛型参数改变了而已,所以在运行时会生成不同的类 Console.WriteLine("---2.如果属性名称和顺序一致,但属性类型不同,那么还是共同使用一个泛型类,只是泛型参数改变了而已,所以在运行时会生成不同的类-----"); var test3 = new { id = 2, name = "maru2" }; Console.WriteLine(test1.GetType() == test3.GetType()); //3.如果数据型名称和类型相同,但顺序不同,那么编译器会重新创建一个匿名类 Console.WriteLine("------------------------------3.如果数据型名称和类型相同,但顺序不同,那么编译器会重新创建一个匿名类------------------------------"); var test4 = new { name="maru4", id = "1" }; Console.WriteLine(test1.GetType() == test4.GetType()); }
运行结果:
二. 匿名方法
1. 这里主要介绍匿名方法在委托中的使用,匿名方法的关键字为:delegate。
2. 传统委托的使用和.Net3.0时代匿名方法引入后的使用
1 public class MyDelegate 2 { 3 //1. 委托的声明 4 public delegate void NoReturnNoPara(); 5 public delegate int WithReturnNoPara(); 6 public delegate void NoReturnWithPara(int id, string name); 7 public delegate MyDelegate WithReturnWithPara(DateTime time); 8 9 //2. 委托的使用(在show方法中调用) 10 public void Show() 11 { 12 //以“有参无返回值委托”为例,介绍委托的各种用法 13 //2.1 用法一 14 { 15 NoReturnWithPara methord = new NoReturnWithPara(this.Test1); 16 methord.Invoke(1, "唐马儒1"); 17 } 18 //2.2 用法二 19 { 20 NoReturnWithPara methord = this.Test1; 21 methord.Invoke(2, "唐马儒2"); 22 } 23 //2.3 用法三 DotNet 2.0 时代 24 { 25 NoReturnWithPara methord = new NoReturnWithPara 26 ( 27 delegate(int id, string name) 28 { 29 Console.WriteLine("{0} {1}", id, name); 30 } 31 ); 32 methord.Invoke(3, "唐马儒3"); 33 } 34 //2.4 用法四 DotNet 3.0 时代 35 { 36 NoReturnWithPara methord = new NoReturnWithPara 37 ( 38 (int id, string name) => 39 { 40 Console.WriteLine("{0} {1}", id, name); 41 } 42 ); 43 methord.Invoke(4, "唐马儒4"); 44 } 45 //2.5 用法五 委托约束 46 { 47 NoReturnWithPara methord = new NoReturnWithPara 48 ( 49 (id,name) => 50 { 51 Console.WriteLine("{0} {1}", id, name); 52 } 53 ); 54 methord.Invoke(5, "唐马儒5"); 55 } 56 //2.6 用法六 (如果方法体只有一行,可以去掉大括号和分好) 57 { 58 NoReturnWithPara methord = new NoReturnWithPara((id, name) => Console.WriteLine("{0} {1}", id, name)); 59 methord.Invoke(6, "唐马儒6"); 60 } 61 //2.7 用法七 62 { 63 NoReturnWithPara methord = (id, name) => Console.WriteLine("{0} {1}", id, name); 64 methord.Invoke(7, "唐马儒7"); 65 methord(7, "唐马儒7"); 66 } 67 68 } 69 private void Test1(int id, string name) 70 { 71 Console.WriteLine("{0} {1}", id, name); 72 } 73 74 private void Test2() 75 { 76 Console.WriteLine("DoNothing"); 77 } 78 79 private void Test3() 80 { 81 Console.WriteLine("DoNothing"); 82 } 83 }
三. 扩展方法
扩展方法即对一些类型进行方法的扩展,扩展方法的三要素为:静态类、静态方法、this关键字。
使用方法:this后面的那个扩展类型.方法名。
下面对string类型扩展,使其可以将string类型转换成int类型,将MyExtend.ToInt(p1) 改装成 p1.ToInt()。
演示重载,并对lambda中的where进行模拟
代码如下:
1 /// <summary> 2 /// 扩展方法的三要素:静态类、静态方法、this关键字 3 /// 使用方法:this关键后面对应的参数类型.扩展方法名 4 /// </summary> 5 public static class MyExtend 6 { 7 /// <summary> 8 /// 1.对string类型进行扩展 9 /// 将MyExtend.ToInt(p1) 改装成 p1.ToInt() 10 /// </summary> 11 /// <param name="p1">需要转换的string对象</param> 12 /// <returns></returns> 13 public static int ToInt(this string p1) 14 { 15 return Convert.ToInt32(p1); 16 } 17 18 /// <summary> 19 /// 2.对string类型进行扩展 20 /// 将p1这个string类型转换成int类型,然后加上p2,最后输出 21 /// 将MyExtend.ToInt(p1,p2) 改装成 p1.ToInt(p2) 22 /// </summary> 23 /// <param name="p1">需要转换的string对象</param> 24 /// <param name="p2">被加的数</param> 25 /// <returns></returns> 26 public static int ToInt(this string p1,int p2) 27 { 28 return Convert.ToInt32(p1)+p2; 29 } 30 /// <summary> 31 /// Lambda模式的where方法自己实现 32 /// </summary> 33 /// <typeparam name="TSource"></typeparam> 34 /// <param name="source"></param> 35 /// <param name="func"></param> 36 /// <returns></returns> 37 public static IEnumerable<TSource> YpfWhere<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> func) 38 { 39 List<TSource> studentList = new List<TSource>(); 40 foreach (TSource item in source) 41 { 42 bool bResult = func.Invoke(item); 43 if (bResult) 44 { 45 studentList.Add(item); 46 } 47 } 48 return studentList; 49 } 50 }
方法调用:
1 Console.WriteLine("------------------------------ 三. 扩展方法----------------------------------"); 2 { 3 { 4 //3.1 对string类型两个扩展方法的调用 5 Console.WriteLine("------------------------------ 3.1 对string类型两个扩展方法的调用----------------------------------"); 6 string msg1 = "123"; 7 //通过静态方法调用 8 Console.WriteLine(MyExtend.ToInt(msg1)); 9 //通过扩展方法调用 10 Console.WriteLine(msg1.ToInt()); 11 Console.WriteLine(msg1.ToInt(1)); 12 } 13 14 }
运行结果: