如何用Mono.Cecil从System.Type获取TypeReference及属性中的类型定义?
当然可以!要从自定义属性的typeof(String)参数里拿到对应的TypeReference或者TypeDefinition,得看你是在运行时通过反射还是**编译后用IL分析工具(比如Mono.Cecil)**来处理,我给你分两种情况说清楚:
1. 运行时用反射获取System.Type(对应IL层面的TypeReference)
如果是在程序运行时处理,直接用.NET自带的反射就能拿到typeof(String)对应的System.Type实例,步骤很简单:
- 先定位到目标属性的
PropertyInfo:var propInfo = typeof(YourClass).GetProperty("SomeProperty"); - 获取标记的自定义属性:
var customAttr = propInfo.GetCustomAttribute<CustomAttribute>(); - 直接访问属性的
Value成员,就能拿到String对应的System.Type:Type stringType = customAttr.Value;
注:运行时的System.Type其实和IL层面的TypeReference是对应关系,如果你需要直接操作IL层面的类型元数据,就得用下面的工具方法。
2. 编译后用IL分析工具(以Mono.Cecil为例)获取TypeReference/TypeDefinition
如果是要处理编译好的程序集(比如做静态分析、代码生成),Mono.Cecil这类工具能直接拿到IL元数据里的TypeReference和TypeDefinition:
- 首先加载目标程序集:
var assembly = AssemblyDefinition.ReadAssembly("YourAssembly.dll"); - 找到包含目标属性的类型:
var targetType = assembly.MainModule.Types.First(t => t.Name == "YourClass"); - 定位到目标属性:
var targetProp = targetType.Properties.First(p => p.Name == "SomeProperty"); - 找到你的
Custom自定义属性:var customAttr = targetProp.CustomAttributes.First(ca => ca.AttributeType.Name == "CustomAttribute"); - 提取
Value命名参数对应的TypeReference:// 假设Value是自定义属性的命名参数 var valueArg = customAttr.Properties.First(p => p.Name == "Value"); TypeReference stringTypeRef = (TypeReference)valueArg.Argument.Value; - 如果需要将
TypeReference转换为TypeDefinition(即类型的完整元数据定义),可以调用Resolve()方法(注意系统类型需要依赖对应的基础类库程序集):TypeDefinition stringTypeDef = stringTypeRef.Resolve();
小提示:如果是String这种系统类型,它的TypeReference指向的是.NET基础类库(比如mscorlib、System.Private.CoreLib)里的类型,调用Resolve()时要确保工具能找到对应的基础类库程序集。
内容的提问来源于stack exchange,提问作者tomwesolowski
相关产品推荐
相关产品推荐

