与其他类型的信息一样,泛型类型的信息的获取方式为:检查表示泛型类型的Type对象。主要的差异在于,泛型类型具有一组表示其泛型类型参数的Type对象。本部分的第一个步骤是检查泛型类型。
通过将类型变量绑定到泛型类型定义的类型参数,可以创建表示构造类型的Type对象。第二个步骤演示此过程。
检查泛型类型及其类型参数
-
获取表示泛型类型的Type实例。在下面的代码中,使用 C# 的typeof运算符(在 Visual Basic 中为GetType,在 Visual C++ 中为typeid)获取类型。有关获取Type对象的其他方法,请参见Type类主题。注意,余下的步骤中,类型包含在名为t的方法参数中。
C#
Type d1 =typeof(Dictionary<,>);
-
使用IsGenericType属性确定类型是否为泛型,然后使用IsGenericTypeDefinition属性确定类型是否为泛型类型定义。
C#
Console.WriteLine(" Is this a generic type? {0}",
t.IsGenericType);
Console.WriteLine(" Is this a generic type definition? {0}",
t.IsGenericTypeDefinition);
-
使用GetGenericArguments方法获取包含泛型类型参数的数组。
C#
Type[] typeParameters = t.GetGenericArguments();
-
对每个类型变量,使用IsGenericParameter属性确定其是不是类型参数(例如,在泛型类型定义中),是不是已为类型参数指定的类型(例如,在构造类型中)。
C#
Console.WriteLine(" List {0} type arguments:",
typeParameters.Length);
foreach( Type tParamintypeParameters )
{
if(tParam.IsGenericParameter)
{
DisplayGenericParameter(tParam);
}
else
{
Console.WriteLine(" Type argument: {0}",
tParam);
}
}
-
在类型系统中,和普通类型一样,泛型类型参数是由Type的实例表示的。下面的代码演示表示泛型类型参数的Type对象的名称和参数位置。此处,参数位置无足轻重;它在检查类型参数(用作其他泛型类型的类型变量)时更有价值。
C#
privatestaticvoidDisplayGenericParameter(Type tp)
{
Console.WriteLine(" Type parameter: {0} position {1}",
tp.Name, tp.GenericParameterPosition);
-
通过使用GetGenericParameterConstraints方法获取单个数组中的所有约束,确定泛型类型参数的基类型约束和接口约束。不保证约束处于任何特定顺序。
C#
Type classConstraint =null;
foreach(Type iConstraintintp.GetGenericParameterConstraints())
{
if(iConstraint.IsInterface)
{
Console.WriteLine(" Interface constraint: {0}",
iConstraint);
}
}
if(classConstraint !=null)
{
Console.WriteLine(" Base type constraint: {0}",
tp.BaseType);
}
else
Console.WriteLine(" Base type constraint: None");
-
使用GenericParameterAttributes属性获取类型参数的特殊约束,如要求其为引用类型。该属性还包含表示方差的值,该值可屏蔽,如下面的代码所示。
C#
GenericParameterAttributes sConstraints =
tp.GenericParameterAttributes &
GenericParameterAttributes.SpecialConstraintMask;
-
特殊约束的属性为标志,表示没有任何特殊约束的标志 (System.Reflection.GenericParameterAttributes.None) 还表示没有协变或逆变。因此,若要测试其中一个条件,必须使用适当的屏蔽。在此情况下,请使用System.Reflection.GenericParameterAttributes.SpecialConstraintMask隔离特殊约束标志。
C#
if(sConstraints == GenericParameterAttributes.None)
{
Console.WriteLine(" No special constraints.");
}
else
{
if(GenericParameterAttributes.None != (sConstraints &
GenericParameterAttributes.DefaultConstructorConstraint))
{
Console.WriteLine(" Must have a parameterless constructor.");
}
if(GenericParameterAttributes.None != (sConstraints &
GenericParameterAttributes.ReferenceTypeConstraint))
{
Console.WriteLine(" Must be a reference type.");
}
if(GenericParameterAttributes.None != (sConstraints &
GenericParameterAttributes.NotNullableValueTypeConstraint))
{
Console.WriteLine(" Must be a non-nullable value type.");
}
}
构造泛型类型的实例
泛型类型和模板类似。除非指定其泛型类型参数的实际类型,否则不能创建泛型类型的实例。若要在运行时使用反射创建实例,需要使用MakeGenericType方法。
构造泛型类型的实例
-
获取表示泛型类型的Type对象。下面的代码以两种不同方式获取泛型类型Dictionary:一种方法使用System.Type.GetType(System.String)方法重载和描述类型的字符串,另一种方法调用构造类型Dictionary<String, Example>(在 Visual Basic 中为Dictionary(Of String, Example))的GetGenericTypeDefinition方法。MakeGenericType方法需要泛型类型定义。
C#
// Use the typeof operator to create the generic type
// definition directly. To specify the generic type definition,
// omit the type arguments but retain the comma that separates
// them.
Type d1 =typeof(Dictionary<,>);
// You can also obtain the generic type definition from a
// constructed class. In this case, the constructed class
// is a dictionary of Example objects, with String keys.
Dictionary<string, Example> d2 =newDictionary<string, Example>();
// Get a Type object that represents the constructed type,
// and from that get the generic type definition. The
// variables d1 and d4 contain the same type.
Type d3 = d2.GetType();
Type d4 = d3.GetGenericTypeDefinition();
-
构造一组用于替换类型参数的类型变量。数组必须包含正确数目的Type对象,并且顺序和对象在类型参数列表中的顺序相同。在这种情况下,键(第一个类型参数)的类型为String,字典中的值是名为Example的类的实例。
C#
Type[] typeArgs = {typeof(string),typeof(Example)};
-
调用MakeGenericType方法将类型变量绑定到类型参数,然后构造类型。
C#
Type constructed = d1.MakeGenericType(typeArgs);
-
使用CreateInstance方法重载来创建构造类型的对象。下面的代码在生成的Dictionary<String, Example>对象中存储Example类的两个实例。
C#
objecto = Activator.CreateInstance(constructed);
示例
下面的代码示例定义DisplayGenericType方法来检查泛型类型定义和代码中使用的构造类型,并显示它们的信息。DisplayGenericType方法演示如何使用IsGenericType、IsGenericParameter和GenericParameterPosition属性以及GetGenericArguments方法。
该示例还定义DisplayGenericParameter方法来检查泛型类型参数并显示其约束。
代码示例定义一组测试类型,包括说明类型参数约束的泛型类型,并演示如何显示这些类型的信息。
示例通过创建一组类型参数并调用MakeGenericType方法,从Dictionary类构造类型。程序对使用MakeGenericType构造的Type对象和使用typeof(Visual Basic 中为GetType)获取的Type对象进行比较,演示这两个对象是相同的。类似地,程序使用GetGenericTypeDefinition方法获取构造类型的泛型类型定义,并将其与表示Dictionary类的Type对象进行比较。
C#
usingSystem;
usingSystem.Reflection;
usingSystem.Collections.Generic;
usingSystem.Security.Permissions;
// Define an example interface.
publicinterfaceITestArgument {}
// Define an example base class.
publicclassTestBase {}
// Define a generic class with one parameter. The parameter
// has three constraints: It must inherit TestBase, it must
// implement ITestArgument, and it must have a parameterless
// constructor.
publicclassTest<T>whereT : TestBase, ITestArgument,new() {}
// Define a class that meets the constraints on the type
// parameter of class Test.
publicclassTestArgument : TestBase, ITestArgument
{
publicTestArgument() {}
}
publicclassExample
{
// The following method displays information about a generic
// type.
privatestaticvoidDisplayGenericType(Type t)
{
Console.WriteLine("/r/n {0}", t);
Console.WriteLine(" Is this a generic type? {0}",
t.IsGenericType);
Console.WriteLine(" Is this a generic type definition? {0}",
t.IsGenericTypeDefinition);
// Get the generic type parameters or type arguments.
Type[] typeParameters = t.GetGenericArguments();
Console.WriteLine(" List {0} type arguments:",
typeParameters.Length);
foreach( Type tParamintypeParameters )
{
if(tParam.IsGenericParameter)
{
DisplayGenericParameter(tParam);
}
else
{
Console.WriteLine(" Type argument: {0}",
tParam);
}
}
}
// The following method displays information about a generic
// type parameter. Generic type parameters are represented by
// instances of System.Type, just like ordinary types.
privatestaticvoidDisplayGenericParameter(Type tp)
{
Console.WriteLine(" Type parameter: {0} position {1}",
tp.Name, tp.GenericParameterPosition);
Type classConstraint =null;
foreach(Type iConstraintintp.GetGenericParameterConstraints())
{
if(iConstraint.IsInterface)
{
Console.WriteLine(" Interface constraint: {0}",
iConstraint);
}
}
if(classConstraint !=null)
{
Console.WriteLine(" Base type constraint: {0}",
tp.BaseType);
}
else
Console.WriteLine(" Base type constraint: None");
GenericParameterAttributes sConstraints =
tp.GenericParameterAttributes &
GenericParameterAttributes.SpecialConstraintMask;
if(sConstraints == GenericParameterAttributes.None)
{
Console.WriteLine(" No special constraints.");
}
else
{
if(GenericParameterAttributes.None != (sConstraints &
GenericParameterAttributes.DefaultConstructorConstraint))
{
Console.WriteLine(" Must have a parameterless constructor.");
}
if(GenericParameterAttributes.None != (sConstraints &
GenericParameterAttributes.ReferenceTypeConstraint))
{
Console.WriteLine(" Must be a reference type.");
}
if(GenericParameterAttributes.None != (sConstraints &
GenericParameterAttributes.NotNullableValueTypeConstraint))
{
Console.WriteLine(" Must be a non-nullable value type.");
}
}
}
[PermissionSetAttribute(SecurityAction.Demand, Name="FullTrust")]
publicstaticvoidMain()
{
// Two ways to get a Type object that represents the generic
// type definition of the Dictionary class.
//
// Use the typeof operator to create the generic type
// definition directly. To specify the generic type definition,
// omit the type arguments but retain the comma that separates
// them.
Type d1 =typeof(Dictionary<,>);
// You can also obtain the generic type definition from a
// constructed class. In this case, the constructed class
// is a dictionary of Example objects, with String keys.
Dictionary<string, Example> d2 =newDictionary<string, Example>();
// Get a Type object that represents the constructed type,
// and from that get the generic type definition. The
// variables d1 and d4 contain the same type.
Type d3 = d2.GetType();
Type d4 = d3.GetGenericTypeDefinition();
// Display information for the generic type definition, and
// for the constructed type Dictionary<String, Example>.
DisplayGenericType(d1);
DisplayGenericType(d2.GetType());
// Construct an array of type arguments to substitute for
// the type parameters of the generic Dictionary class.
// The array must contain the correct number of types, in
// the same order that they appear in the type parameter
// list of Dictionary. The key (first type parameter)
// is of type string, and the type to be contained in the
// dictionary is Example.
Type[] typeArgs = {typeof(string),typeof(Example)};
// Construct the type Dictionary<String, Example>.
Type constructed = d1.MakeGenericType(typeArgs);
DisplayGenericType(constructed);
objecto = Activator.CreateInstance(constructed);
Console.WriteLine("/r/nCompare types obtained by different methods:");
Console.WriteLine(" Are the constructed types equal? {0}",
(d2.GetType()==constructed));
Console.WriteLine(" Are the generic definitions equal? {0}",
(d1==constructed.GetGenericTypeDefinition()));
// Demonstrate the DisplayGenericType and
// DisplayGenericParameter methods with the Test class
// defined above. This shows base, interface, and special
// constraints.
DisplayGenericType(typeof(Test<>));
}
}
分享到:
相关推荐
机械设计定量旋转包装机sw16可编辑全套设计资料100%好用.zip.zip
层级关系-关系图表-清新时尚彩虹色 -3
图表分类ppt
内容概要:本文档针对神卓组网设备提供详细的配置指导。重点介绍了两大常见的设置问题及其解决方案:一是网关设置冲突的问题,文中详细解释了需要避免与本地及其他相关联网络已使用的网关地址相重复,如避开常用的192.168.1.1以及神卓默认的192.168.51.1等。二是对于远程网段信息的误填,强调在配置中正确添加对方的IP网段而不是单一地址的重要性和具体步骤。这些信息可以帮助用户确保组网过程更加顺利、高效,有效规避可能存在的障碍与困难。 适用人群:适用于正在部署和管理中小型网络的企业管理员,尤其是那些缺乏专业IT知识但希望通过简单易懂的方式解决组网问题的小白用户。 使用场景及目标:旨在帮助技术人员和非专业人士掌握并解决神卓组网设备中最棘手且普遍遇到的技术难题—特别是有关于跨区域网络互联中网关设置与目标网络网段填写错误的情况。 其他说明:阅读本文时需要注意特别事项提示部分的内容,这将有助于预防由于错误操作导致无法连通的情况发生,并提升网络安全性和稳定性。
基于微信小程序的语言课学习系统设计与实现.docx
手机模型对比图PPT模板素材
立体箭头冲突关系PPT模板
资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,拿来就能用。放心下载使用!源码、说明、论文、数据集一站式服务,拿来就能用的绝对好资源!!! 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、大作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
图表分类ppt
码垛机图纸,伺料码垛机图纸,腻子粉码垛机图纸,可借鉴学习,参考设计
文本说明框联动关系PPT模板
基于Android的修图软件-课设
内容概要:本文档提供了一份详尽的 Ubuntu 20.04 安装指南,涵盖物理机和虚拟机两种安装方式。针对物理机,依次讲解了准备阶段(制作启动U盘、配置BIOS/UEFI)、系统安装(选择语言、键鼠设置、联网配置以及重点磁盘分区)、启动进入新系统的完整步骤;针对虚拟机,则围绕常用软件(VMware或VirtualBox)的新虚拟机制作、系统配置(含ISO挂载)等流程予以阐述。磁盘分区部分尤其细致,明确不同分区(根分区、Home、启动、Swap)的作用和推荐分配值,特别区分了手动和自动两种分区模式各自的优劣,方便不同类型用户根据需求做出合适的选择。 适用人群:无论是初次接触Ubuntu的新用户还是希望掌握双平台部署技巧的老手均能从中受益。 使用场景及目标:适用于需要安装Ubuntu作为独立操作系统或在现有宿主机中快速建立Linux测试环境的专业技术人员或计算机爱好者,帮助他们顺利地完成操作系统安装并理解其关键配置要点。 其他说明:由于不同硬件和个人偏好可能导致实际操作中存在些许差异,读者可根据自身情况进行适当调整。文中提到的操作步骤尽量保持通用性和简明性,使更多人更容易理解和上手。
ACCENTURE - How luxury brands are reinventing for success_CAIG
===如资源质量问题,可半价退款,代下全网资源,价格公道==== 基于Vue + Echarts 构建的数据可视化平台,酷炫大屏展示模板和组件库,持续更新各行各业实用模板和炫酷小组件。.zip。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
springboot项目驾校管理系统,含有完整的源码和报告文档
随机生成给定颗粒分布多孔介质 孔隙率可控
IMG20250110151521.jpg
springboot项目基于SpringBoot的私房菜定制上门服务系统的设计与实现,含有完整的源码和报告文档
171-西门子1200PLC机器人控制程序模板,程序模板清晰明了,容易看懂,有注释,硬件采用1214CPU,触摸屏采用KTP700系列。 打开软件采用博图V15.1及以上。