如何获取通过MetadataType元数据类分配的自定义特性?
解决MetadataType关联的自定义特性获取问题
这是个很典型的坑——默认的反射API不会自动处理MetadataType特性,所以你直接用GetCustomAttribute只能拿到目标类本身属性上的标记,找不到元数据类里的特性。别担心,我们有两种靠谱的解决办法:
方法一:手动封装反射逻辑(通用场景)
我们可以写一个扩展方法,自动检查目标类的MetadataType关联,然后去元数据类里找对应的属性特性。这样不管什么场景都能用:
using System; using System.ComponentModel.DataAnnotations; using System.Reflection; public static class ReflectionExtensions { public static T GetCustomAttributeWithMetadata<T>(this PropertyInfo property) where T : Attribute { // 先检查属性本身是否有该特性 var directAttr = property.GetCustomAttribute<T>(); if (directAttr != null) return directAttr; // 获取当前类的MetadataType特性,拿到元数据类类型 var metadataAttr = property.DeclaringType.GetCustomAttribute<MetadataTypeAttribute>(); if (metadataAttr == null) return null; // 在元数据类中找到同名属性 var metadataProperty = metadataAttr.MetadataClassType.GetProperty(property.Name); if (metadataProperty == null) return null; // 返回元数据属性上的目标特性 return metadataProperty.GetCustomAttribute<T>(); } }
然后修改你的Main方法调用:
static void Main(string[] args) { TestClass test = new TestClass(); PropertyInfo property = test.GetType().GetProperty("Poperty"); TestAttribute attr = property.GetCustomAttributeWithMetadata<TestAttribute>(); // 现在attr就能正确获取到元数据类里的TestAttribute了 }
方法二:用TypeDescriptor(适用于DataAnnotations场景)
如果你本来就在用System.ComponentModel.DataAnnotations相关的框架,TypeDescriptor已经帮我们处理了MetadataType的解析,直接用它更省事:
using System.ComponentModel; using System.ComponentModel.DataAnnotations; static void Main(string[] args) { // 获取属性的TypeDescriptor PropertyDescriptor propertyDescriptor = TypeDescriptor.GetProperties(typeof(TestClass))["Poperty"]; // 从属性描述符里获取特性 TestAttribute attr = propertyDescriptor.Attributes[typeof(TestAttribute)] as TestAttribute; }
注意事项
- 属性名称要完全匹配(大小写敏感),元数据类里的属性名称和目标类的属性名必须一致,否则找不到。
MetadataType特性默认只能给一个类关联一个元数据类,所以不用考虑多元数据的情况。
内容的提问来源于stack exchange,提问作者r00xus
相关产品推荐
相关产品推荐

