[读书笔记]C#学习笔记四: C#2.0泛型 可控类型 匿名方法和迭代器
2016-01-20 22:00
861 查看
前言
C#1.0的委托特性使方法作为其他方法的参数来传递,而C#2.0 中提出的泛型特性则使类型可以被参数化,从而不必再为不同的类型提供特殊版本的实现方法。
另外C#2.0还提出了可空类型,匿名方法和迭代器3个优美的特性。
1,泛型
1.1 泛型是什么
泛型的英文表述是"generic", 这个单词意为通用的。从字面意思可知,泛型代表的就是"通用类型",它可以代替任意的数据类型,使类型参数化,
从而达到之实现一个方法就可以操作多种数据类型的目的。泛型是将方法实现行为与方法操作的数据类型分离,实现了代码重用。
在以上的代码中,List<T> 是.Net 类库中实现的泛型类型,T是泛型参数(可理解为形参), 如果想实例化一个泛型类型,必须传入实际的参数类型。
泛型除了可以实现代码重用外, 还提供了更好的性能和类型安全特性. 前面关于拆箱装箱讲过. 应用类型和值类型间存在着相互转换,转换的过程称为装箱和拆箱. 这对过程会引起一定的性能损失. 而泛型是避免性能损失的有效方法.
1.2全面解析泛型
在前面的泛型代码中, T就是类型参数. 无论调用类型方法还是初始化泛型实例, 都需要用真实类型来替换T. 可以将T理解为类型的一个占位符, 即告诉编译器, 在调用泛型时必须为其指定一个实际类型.
1.2.1
已构造泛型又可分为开放类型和密封类型. 其中, 开放类型是指包含类型参数的泛型,所有未绑定的泛型类型都属于开放类型; 而封闭类型则是指那些已经为每一个类型参数都传递了司机数据类型的泛型.
1.2.2
泛型中的静态字段和静态函数问题
静态数据类型是属于类型的. 对于静态之端来说, 如果某个MyClass类中定义了一个静态字段X, 则不管之后创建了多少个该类的实例,也不管从该类派生出多少个实例,
都只存在一个MyClass.x字段. 但泛型类型却并非如此, 每个封闭的泛型类型中都有仅属于他自己的静态数据.
运行结果图:
View Code
4.3迭代器的执行过程图解
PS: 这两天比较闲 便更新的比较频繁. 写完这个系列也等于把这本书又重新读了一遍, 仍有不少的收获. 勉励自己多读书, 多记录, 加油! 2016/01/20
C#1.0的委托特性使方法作为其他方法的参数来传递,而C#2.0 中提出的泛型特性则使类型可以被参数化,从而不必再为不同的类型提供特殊版本的实现方法。
另外C#2.0还提出了可空类型,匿名方法和迭代器3个优美的特性。
1,泛型
1.1 泛型是什么
泛型的英文表述是"generic", 这个单词意为通用的。从字面意思可知,泛型代表的就是"通用类型",它可以代替任意的数据类型,使类型参数化,
从而达到之实现一个方法就可以操作多种数据类型的目的。泛型是将方法实现行为与方法操作的数据类型分离,实现了代码重用。
class Program { static void Main(string[] args) { //用int作为实际参数来促使花泛型类型 List<int> intList = new List<int>(); //从int列表添加元素3 intList.Add(3); //用string作为实际参数来初始化泛型类型 List<string> stringList = new List<string>(); //从string列表添加元素 stringList.Add("wanmg-meng"); } }
在以上的代码中,List<T> 是.Net 类库中实现的泛型类型,T是泛型参数(可理解为形参), 如果想实例化一个泛型类型,必须传入实际的参数类型。
泛型除了可以实现代码重用外, 还提供了更好的性能和类型安全特性. 前面关于拆箱装箱讲过. 应用类型和值类型间存在着相互转换,转换的过程称为装箱和拆箱. 这对过程会引起一定的性能损失. 而泛型是避免性能损失的有效方法.
1.2全面解析泛型
在前面的泛型代码中, T就是类型参数. 无论调用类型方法还是初始化泛型实例, 都需要用真实类型来替换T. 可以将T理解为类型的一个占位符, 即告诉编译器, 在调用泛型时必须为其指定一个实际类型.
1.2.1
已构造泛型又可分为开放类型和密封类型. 其中, 开放类型是指包含类型参数的泛型,所有未绑定的泛型类型都属于开放类型; 而封闭类型则是指那些已经为每一个类型参数都传递了司机数据类型的泛型.
//声明开放泛型类型 public class DictionaryStringKey<T> : Dictionary<string, T> { } class Program { static void Main(string[] args) { //Dictionary<,> 是一个开放类型, 它有两个类型参数 Type t = typeof(Dictionary<,>); //DictionaryStringKey<int> 是一个封闭类型 t = typeof(DictionaryStringKey<int>); } }
1.2.2
泛型中的静态字段和静态函数问题
静态数据类型是属于类型的. 对于静态之端来说, 如果某个MyClass类中定义了一个静态字段X, 则不管之后创建了多少个该类的实例,也不管从该类派生出多少个实例,
都只存在一个MyClass.x字段. 但泛型类型却并非如此, 每个封闭的泛型类型中都有仅属于他自己的静态数据.
//泛型类型, 具有一个类型参数 public static class TypeWithStaticField<T> { //静态字段 public static string field; //静态构造函数 public static void OutField() { Console.WriteLine(field + ":" + typeof(T).Name); } } //非泛型类 public static class NoGenericTypeWithStaticField { public static string field; public static void OutField() { Console.WriteLine(field); } } class Program { static void Main(string[] args) { //使用不同类型实参来实例化泛型实例 TypeWithStaticField<int>.field = "一"; TypeWithStaticField<string>.field = "二"; TypeWithStaticField<Guid>.field = "三"; //对于非泛型类型, 此时field只会有一个值, 每次赋值都改变了原来的值 NoGenericTypeWithStaticField.field = "非泛型类静态字段一"; NoGenericTypeWithStaticField.field = "非泛型类静态字段二"; NoGenericTypeWithStaticField.field = "非泛型类静态字段三"; NoGenericTypeWithStaticField.OutField(); //证明每个封闭类型都有一个静态字段 TypeWithStaticField<int>.OutField(); TypeWithStaticField<string>.OutField(); TypeWithStaticField<Guid>.OutField(); Console.ReadKey(); } }
运行结果图:
//使用yield自定义实现迭代器 class Program { static void Main(string[] args) { //创建一个对象 Friends friendCollection = new Friends(); //Friends实现了IEnumerable,所以可以使用foreach语句进行遍历 foreach (Friend f in friendCollection) { Console.WriteLine(f.Name); } Console.ReadKey(); } } //朋友类 public class Friend { private string name; public string Name { get { return name; } set { name = value; } } public Friend(string name) { this.name = name; } } //朋友集合 public class Friends : IEnumerable { private Friend[] friendArray; public Friends() { friendArray = new Friend[] { new Friend("张三"), new Friend("李四"), new Friend("王五") }; } //索引器 public Friend this[int index] { get { return friendArray[index]; } } public int Count { get { return friendArray.Length; } } //C#2.0简化了迭代器的实现 public IEnumerator GetEnumerator() { for (int i = 0; i < friendArray.Length; i++) { //在C#2.0中, 只需要使用下面的语句就可以实现一个迭代器 yield return friendArray[i]; //这里使用yield 简化了IEnumerator GetEnumerator中的Current() MoveNext() Reset() 方法的实现 } } }
View Code
4.3迭代器的执行过程图解
PS: 这两天比较闲 便更新的比较频繁. 写完这个系列也等于把这本书又重新读了一遍, 仍有不少的收获. 勉励自己多读书, 多记录, 加油! 2016/01/20
相关文章推荐
- 跟siki老师学C#第六天
- c#set 和get用法
- C#图形验证码
- 递归全排列(C#)
- C#类在什么时候分配内存
- c#程序内存分配
- C#中new的用法,及与override的区别
- C#关键字-运算符关键字-new
- C#AutoResetEvent和ManualResetEvent的区别
- C# 保留2位小数
- C#三级联动
- C#XML与二进制相互转换
- c#图片添加水印
- C#语法糖(Csharp Syntactic sugar)大汇总
- C# 串口与窗体应用程序的连接
- C#中Array、arrayList、List的优缺点
- c# 模拟提交带文件上传的表单
- C# 简陋的远程工具
- C#基础知识图谱
- C#基础知识图谱