C# 2 泛型、可空值类型、迭代器及次要特征
一、泛型
泛型的好处:你可以使用泛型编写通用代码,可以在多个地方使用相同的类型,而无需事先知道该类型是什么。
泛型的使用:
1、类、方法及其返回类型、嵌套类型、结构体、接口和委托都可以是泛型。
2、枚举、字段、属性、索引器、构造函数、事件、终结器不可以是泛型。
3、即使方法的签名完全相同,你也可以创建具有相同名称但不同泛型参数数量的方法。但需要注意的是,泛型类型参数名称不具备方法签名效用。
4、Tuple支持传递多个泛型参数创建实例,便于编写通用代码。但是,在传入编译器无法推断的类型(如null)时,需显示指定泛型参数类型,否则,报编译时错误。
5、在嵌套泛型中,每一层声明的泛型参数都有独立作用域。即使名称相同,也代表不同的类型参数;内层会遮蔽外层,两者互不关联。
泛型约束:
1、where T : class 约束引用类型,不仅可以传递类,还可以传递接口、委托、字符串、数组等。
2、where T : struct 约束非空值类型,如结构、枚举等,但不包括Nullable。
3、where T : new() 约束必须具有无参构造函数,该约束允许在代码主体中使用new T()来创建实例。
4、约束其他类型,如where T : Control,where T : IFormattable,where T : T2。分别对应基类约束、接口约束、类型参数约束。
5、当泛型声明中存在多个类型参数时,每个参数的约束条件可以不同。
typeof操作符:
1、typeof 操作符既可用于获取具体类型(如 typeof(T)),也可用于获取开放泛型类型定义(如 typeof(List<>))。
2、对于开放泛型,尖括号内逗号的数量表示泛型参数个数:参数个数 = 逗号数 + 1,例如 typeof(Dictionary<,>)。
default操作符:
默认操作符default的结果就是该参数的默认值,它常用于泛型参数类型。
注意:
1、当代码在泛型类型或方法中执行时,类型参数始终指向封闭的构造类型。
2、当代码真正执行时,CLR 一定已经知道 T 是什么,不存在“运行中的开放泛型实例”。
二、可空值类型
1、null的目的是表达信息缺失。
2、Nullable 用于表达可空值类型。
3、Nullable 类型的相等逻辑不是引用比较,而是基于:1、HasValue;2、Value 的相等性。使用Equals(object)和GetHashCode()方法判断是否相等。
4、int o = 1; o.GetType() 等同于 typeof(int),当值类型调用GetType()函数时,首先会进行装箱,但如果这是个空的类型则会抛异常。但使用typeof()操作符则不会进行装箱,因为它在编译期获取类型信息。
5、在Nullable中,null实际上代表该类型在HasValue为false时的真实值,而非空引用。
6、as 是一种安全的类型转换(失败返回 null),但它只适用于引用类型与可空值类型。
三、迭代器
1、迭代器的显著特征之一:延迟执行。即仅在需要计算结果时执行代码。
2、可以把IEnumerable看作一本书,而把IEnumerator看作书签。
3、如果调用迭代器的MoveNext()方法结果为true,说明已移动到下一个“书签”,如果结果为false,表示序列结束。此外,只有在调用MoveNext()方法时才会开始执行迭代器代码。
4、迭代器终止的三种情况:1.抛出异常;2.该方法已执行至结束;3.执行至yield break语句。
5、yield return的意思是暂停并返回值。当再次调用MoveNext()时,会重新恢复并继续执行后面的代码。
6、迭代器中的finally块只在迭代器释放时执行一次,而不是每次yield return都执行。
7、如果你直接获取枚举器(var enumerator = collection.GetEnumerator())并手动调用 MoveNext(),若没有遍历所有序列,则需要手动调用Dispose。
8、迭代器中的位置是由状态机记录的。
四、次要特征
1、C# partial 仅用于类、结构体、接口、记录和无返回值的方法(C#版本不同,限制不同)。
2、静态类永远无法实例化,但是静态类内可以编写嵌套的非静态类,且该类可以定义非静态方法。静态类内不能声明实例成员(包括变量、方法等),它不能作为类型参数使用。
3、命名空间别名可以解决命名冲突,extern alias 是按程序集区分类型的语言机制。
4、可以使用 #pragma warning disable CSxxxx 禁用指定编译警告,使用 #pragma warning restore CSxxxx 恢复警告。通常应优先修复警告,而不是禁用它们。
5、固定大小缓冲区仅适用于不安全代码,并且只能在结构体内部使用。

浙公网安备 33010602011771号