开发网站的意义,微信小程序在哪里?,阿里云免费域名注册,wordpress腾讯视频插件下载本文内容
定义和使用泛型泛型的利与弊类库和语言支持嵌套类型和泛型
借助泛型#xff0c;你可以根据要处理的精确数据类型定制方法、类、结构或接口。 例如#xff0c;不使用允许键和值为任意类型的 Hashtable 类#xff0c;而使用 DictionaryTKey,TValue 泛型类并…本文内容
定义和使用泛型泛型的利与弊类库和语言支持嵌套类型和泛型
借助泛型你可以根据要处理的精确数据类型定制方法、类、结构或接口。 例如不使用允许键和值为任意类型的 Hashtable 类而使用 DictionaryTKey,TValue 泛型类并指定允许的密钥和值类型。 泛型的优点包括代码的可重用性增加类型安全性提高。
1、定义和使用泛型
泛型是为所存储或使用的一个或多个类型具有占位符类型形参的类、结构、接口和方法。 泛型集合类可以将类型形参用作其存储的对象类型的占位符类型形参呈现为其字段的类型和其方法的参数类型。 泛型方法可将其类型形参用作其返回值的类型或用作其形参之一的类型。 以下代码举例说明了一个简单的泛型类定义。
public class GenericT
{public T Field;
}创建泛型类的实例时指定用于替代类型形参的实际类型。 在类型形参出现的每一处位置用选定的类型进行替代这会建立一个被称为构造泛型类的新泛型类。 你将得到根据你选择的类型而定制的类型安全类如以下代码所示。
public static void Main()
{Genericstring g new Genericstring();g.Field A string;//...Console.WriteLine(Generic.Field \{0}\, g.Field);Console.WriteLine(Generic.Field.GetType() {0}, g.Field.GetType().FullName);
}1.1 泛型术语
介绍 .NET 中的泛型需要用到以下术语 泛型类型定义 是用作模板的类、结构或接口声明带有可包含或使用的类型的占位符。 例如 System.Collections.Generic.DictionaryTKey,TValue 类可以包含两种类型密钥和值。 由于泛型类型定义只是一个模板所以你无法创建作为泛型类型定义的类、结构或接口的实例。 泛型类型参数或类型参数是泛型类型或方法定义中的占位符。 System.Collections.Generic.DictionaryTKey,TValue 泛型类型具有两个类型形参 TKey 和 TValue它们分别代表密钥和值的类型。 构造泛型类型或 构造类型是为泛型类型定义的泛型类型形参指定类型的结果。 泛型类型实参 是被泛型类型形参所替代的任何类型。 常见术语泛型类型包括构造类型和泛型类型定义。 借助泛型类型参数的协变和逆变可以使用类型自变量的派生程度比目标构造类型更高协变或更低逆变的构造泛型类型。 协变和逆变统称为“变体” 。 约束是对泛型类型参数的限制。 例如你可能会将一个类型形参限制为实现 System.Collections.Generic.IComparerT 泛型接口的类型以确保可对该类型的实例进行排序。 此外你还可以将类型形参限制为具有特定基类、具有无参数构造函数或作为引用类型或值类型的类型。 泛型类型的用户不能替换不满足约束条件的类型实参。 泛型方法定义 是具有两个形参列表的方法泛型类型形参列表和形参列表。 类型形参可作为返回类型或形参类型出现如以下代码所示。
T GenericT(T arg)
{T temp arg;//...return temp;
}泛型方法可出现在泛型或非泛型类型中。 值得注意的是方法不会仅因为它属于泛型类型或甚至因为它有类型为封闭类型泛型参数的形参而成为泛型方法。 只有当方法有属于自己的类型形参列表时才是泛型方法。 在以下代码中只有方法 G 是泛型方法。
class A
{T GT(T arg){T temp arg;//...return temp;}
}
class GenericT
{T M(T arg){T temp arg;//...return temp;}
}2、泛型的利与弊
使用泛型集合和委托有很多好处 类型安全。 泛型将类型安全的负担从你那里转移到编译器。 没有必要编写代码来测试正确的数据类型因为它会在编译时强制执行。 降低了强制类型转换的必要性和运行时错误的可能性。 代码更少且可以更轻松地重用代码。 无需从基类型继承无需重写成员。 例如可立即使用 LinkedListT 。 例如你可以使用下列变量声明来创建字符串的链接列表 LinkedListstring llist new LinkedListstring();性能更好。 泛型集合类型通常能更好地存储和操作值类型因为无需对值类型进行装箱。 泛型委托可以在无需创建多个委托类的情况下进行类型安全的回调。 例如 PredicateT 泛型委托允许你创建一种为特定类型实现你自己的搜索标准的方法并将你的方法与 Array 类型比如 Find、 FindLast和 FindAll方法一起使用。 泛型简化动态生成的代码。 使用具有动态生成的代码的泛型时无需生成类型。 这会增加方案数量在这些方案中你可以使用轻量动态方法而非生成整个程序集。
以下是泛型的一些局限 泛型类型可从多数基类中派生如 MarshalByRefObject 约束可用于要求泛型类型形参派生自诸如 MarshalByRefObject的基类。 不过.NET 不支持上下文绑定的泛型类型。 泛型类型可派生自 ContextBoundObject但尝试创建该类型实例会导致 TypeLoadException。 枚举不能具有泛型类型形参。 枚举偶尔可为泛型例如因为它嵌套在被定义使用 Visual Basic、C# 或 C 的泛型类型中。 轻量动态方法不能是泛型。 在 Visual Basic、C# 和 C 中包含在泛型类型中的嵌套类型不能被实例化除非已将类型分配给所有封闭类型的类型形参。 另一种说法是在反射中定义使用这些语言的嵌套类型包括其所有封闭类型的类型形参。 这使封闭类型的类型形参可在嵌套类型的成员定义中使用。 通过在动态程序集中触发代码或通过使用 Ilasm.exe (IL 汇编程序) 定义的嵌套类型不需要包括其封闭类型的类型参数然而如果不包括类型参数就不会在嵌套类的范围内。
3、类库和语言支持
.NET 在以下命名空间中提供了大量泛型集合类 System.Collections.Generic 命名空间包含 .NET 提供的大部分泛型集合类型如 ListT 和 DictionaryTKey,TValue 泛型类。 System.Collections.ObjectModel 命名空间包含向类用户公开对象模型的其他泛型集合类型如 ReadOnlyCollectionT 泛型类。
System 命名空间提供实现排序和等同性比较的泛型接口还提供事件处理程序、转换和搜索谓词的泛型委托类型。
已将对泛型的支持添加到 System.Reflection 命名空间以检查泛型类型和泛型方法、 System.Reflection.Emit 以发出包含泛型类型和方法的动态程序集和 System.CodeDom 以生成包括泛型的源图。
公共语言运行时提供了新的操作码和前缀来支持 Microsoft 中间语言 (MSIL) 中的泛型类型包括 Stelem、 Ldelem、 Unbox_Any、 Constrained和 Readonly。
Visual C、C# 和 Visual Basic 都对定义和使用泛型提供完全支持。
4、嵌套类型和泛型
嵌套在泛型类型中的类型可取决于封闭泛型类型的类型参数。 公共语言运行时将嵌套类型看作泛型即使它们不具有自己的泛型类型形参。 创建嵌套类型的实例时必须指定所有封闭泛型类型的类型实参。