CLR via C#关于泛型(Generics )的摘录
2021-04-08 12:26
标签:lis 两个泛型 col swa 命名空间 [] 默认 ack 是什么 泛型,是CLR和编程语言提供的一种特殊机制,它支持另一种形式的代码重用,即“算法重用”。 简单的说,开发人员先定义好一个算法,比如排序、搜索、交换、比较或者转换等。但是,定义算法的开发人员并不设改算法要操作什么数据类型:改算法可广发地应用于不同类型的对象。然后,另一个开发人员只要指定了算法要操作的具体数据类型,就可以开始使用这个现成的算法了。例如,可用一个排序算法来操作Int32 和String等类型的对象。 1、大多数算法都封装在一个类型中,CLR允许创建泛型引用类型和泛型值类型,但不允许创建泛型枚举类型。除此之外,CLR还允许创建泛型接口和反省委托。所以,CLR允许在引用类型、值类型或接口中定义泛型方法。 2、泛型的优势: 3、Framework类库中的泛型 泛型最明显的应用就是集合类。FCL已经定义了几个泛型集合类。其中大多数都在System.Collections.Generic和System.Collection.ObjectModel命名空间中。 4、泛型类型和继承: 泛型类型仍然是类型,所以它能从其他任何类型派生。由于List 5、泛型接口:泛型的主要作用就是定义泛型的引用类型和值类型。然而,对泛型接口的支持对CLR来说也很重要。没有泛型接口,每次试图使用一个非泛型接口(如IComparable)来操纵一个值类型,都会发生装箱,而且会失去编译时的类型安全性。 以下泛型接口定义时FCL的一部分(在System.Collections.Generic 命名空间中): 下面的示例类型实现了上述泛型接口,而且指定了类型实参。注意,Triangle对象可枚举一组Point对象。还要注意,Current属性具有Point数据类型。 6、泛型委托:CLR支持泛型委托,目的是保证任何类型的对象都能以一种类型安全的方式传给一个回调方法。此外,泛型委托允许一个值类型实例在传给一个回调方法时不执行任何装箱处理。 例如,假定像下面这样定义一个委托泛型: 编译器会将它转成一个类,该类在逻辑上可以这样表示: 7、泛型方法:定义泛型类、结构或接口时,这些类型中定义的任何方法都可引用由类型指定的一个类型参数。类型参数可以作为方法的参数,作为方法的返回值,或者作为方法内部定义的一个局部变量来使用。 在这个例子中,GenericType类定义了自己的类型参数(T),Converter 方法也定义了自己的类型参数(TOutput)。这样的GenericType可以处理任何类型。Convert方法能将m_value字段引用的对象转换成任意类型——具体取决于传给它的类型实参是什么。泛型方法的存在,为开发人员提供了极大的灵活性。 Swap方法: 可以在代码中像这样调用Swap: 8、其他可验证问题 1)、泛型类型变量的转型:将一个泛型类型变量转型为另一个类型是非法的,除非将其转型为与一个约束兼容的类型。 上述两行会造成编译器报错,因为T可能是任意类型,无法保证能成功转型。为了修改上述代码使其能编译通过,可以先转型为Object: 虽然代码现在能够编译,但CLR仍有可能在运行时抛出一个InvalidCastException异常。 如果试图转型为一个引用类型,还可以使用C#的as操作符。下面对代码进行了修改,将操作符与Sting配合使用(因为Int32是一个值类型): 2)、将一个泛型类型变量设为默认值 将泛型类型变量设为null是非法的,除非将泛型类型约束成一个引用类型。 由于未对T进行约束,所以它可能是一个值类型,而将值类型的一个变量设为null是不可能的。如果T被约束成引用类型,将temp设为null就是合法的,代码能顺利编译并运行。 以上代码中的default关键字告诉C#编译器和CLR的JIT编译器,如果T是一个引用类型,就将temp设为null;如果T是一个值类型,就将temp的所有位设为0。 3)、将一个泛型类型变量与null进行比较 无论泛型类型是否被约束,使用==或!=操作符将一个泛型类型变量与null进行比较都是合法的。 注:如果T被约束成为一个struct,C#编译器会报错。值类型的变量不能与null进行比较,因为结果始终是相同的。 4)、两个泛型变量相互比较 如果泛型类型参数不是一个引用类型,对同一个泛型类型的两个变量进行比较是非法的。 在这个例子中,T为进行约束。虽然两个引用类型的变量相互比较是合法的,单两个值类型的变量相互比较是非法的,除非值类型重载了 ”==“ 操作符。 不允许将类型参数约束成一个具体的值类型,因为值类型隐式密封,不可能存在从值类型派生的类型。如果允许将类型参数约束成一个具体的值类型,那么泛型方法会被约束为只支持该具体类型,这还不如写一个非泛型的方法呢! 5)、泛型类型变量作为操作数使用 最后要注意的是,将操作符应用于泛型类型的操作数,会出现大量的问题。不能将这些操作符(+,-,*,/)应用于泛型类型的变量,因为编译器在编译时无法确定类型。 将T约束成为一个struct,而且使用default(T)将sum 和n初始化为0.编译仍会报错。运算符”
CLR via C#关于泛型(Generics )的摘录 标签:lis 两个泛型 col swa 命名空间 [] 默认 ack 是什么 原文地址:https://www.cnblogs.com/meng9527/p/9056562.htmlprivate static void SomeMethod() {
// Construct a List that operates on DateTime objects
List
public interface IEnumerator
internal sealed class Triangle : IEnumerator
public delegate TReturn CallMe
public sealed class CallMe
internal sealed class GenericType
private static void Swap
private static void CallingSwap() {
Int32 n1 = 1, n2 = 2;
Console.WriteLine("n1={0}, n2={1}", n1, n2);//1,2
Swap
private static void CastingAGenericTypeVariable1
private static void CastingAGenericTypeVariable2
private static void CastingAGenericTypeVariable3
private static void SettingAGenericTypeVariableToNull
//无法将null转换为类型参数“T",因为它可能是不为null的值类型。请考虑改用default(‘T‘)
}private static void SettingAGenericTypeVariableToDefaultValue
private static void ComparingAGenericTypeVariableWithNull
private static void ComparingTwoGenericTypeVariables
private static T Sum
下一篇:C# web 后台页面间的跳转
文章标题:CLR via C#关于泛型(Generics )的摘录
文章链接:http://soscw.com/essay/72866.html