如何读取类、方法上附加的Attribute特性的构造参数与对象属性
完整实现代码
你可以直接在MyOwnAttribute类中补充如下静态方法即可覆盖全部四类需求:
using System.Reflection; using System.Linq; public class MyOwnAttribute : Attribute { // 兼容两种构造场景的属性定义 public string MyProperty1 { get; set; } public string MyProperty2 { get; set; } public string[] MyProperties { get; set; } // 双参数构造 public MyOwnAttribute(string p1 = null, string p2 = null) { MyProperty1 = p1?.ToString(); MyProperty2 = p2?.ToString(); MyProperties = new[] { p1, p2 }.Where(x => x != null).ToArray(); } // 多参数构造 public MyOwnAttribute(params object[] p) { MyProperties = p.Select(s => s?.ToString()).ToArray(); if (p.Length >= 1) MyProperty1 = p[0]?.ToString(); if (p.Length >= 2) MyProperty2 = p[1]?.ToString(); } #region 需求1:读取类上Attribute的构造参数列表 public static object[] GetClassAttributeValues(Type classType) { // 方式1:直接读取Attribute中存储的参数属性(性能更高) var attrib = GetCustomAttribute(classType, typeof(MyOwnAttribute)) as MyOwnAttribute; return attrib?.MyProperties ?? Array.Empty<object>(); // 方式2:无需修改Attribute定义,直接读取元数据构造参数(兼容所有自定义Attribute) /* return CustomAttributeData.GetCustomAttributes(classType) .FirstOrDefault(ad => ad.AttributeType == typeof(MyOwnAttribute))? .ConstructorArguments.Select(ca => ca.Value).ToArray() ?? Array.Empty<object>(); */ } #endregion #region 需求2:读取方法上Attribute的实例 public static MyOwnAttribute GetMethodAttributes<T>(string methodName) { var methodInfo = typeof(T).GetMethod(methodName); return methodInfo == null ? null : GetCustomAttribute(methodInfo, typeof(MyOwnAttribute)) as MyOwnAttribute; } #endregion #region 你已实现的另外两个方法(对齐格式) public static object[] GetMethodAttributeValues<T>(string methodName) { var methodInfo = typeof(T).GetMethod(methodName); if (methodInfo == null) return Array.Empty<object>(); var attrib = GetCustomAttribute(methodInfo, typeof(MyOwnAttribute)) as MyOwnAttribute; return attrib?.MyProperties ?? Array.Empty<object>(); } public static MyOwnAttribute GetClassAttributes(Type classType) { return GetCustomAttribute(classType, typeof(MyOwnAttribute)) as MyOwnAttribute; } #endregion }
调用验证示例
测试用的标记类和方法
[MyOwnAttribute("类参数1", "类参数2", "类参数3")] public class clsA { [MyOwnAttribute("World", "2")] public void MyMethod2() { } }
问题1调用(读取类的Attribute构造参数)
var classAttribParamValues = MyOwnAttribute.GetClassAttributeValues(typeof(clsA)); // 输出:类参数1 类参数2 类参数3 string.Join(' ', classAttribParamValues.Select(s => s ?? "")).Dump();
问题2调用(读取方法的Attribute实例属性)
var methodAttrib = MyOwnAttribute.GetMethodAttributes<clsA>(nameof(clsA.MyMethod2)); // 输出:World methodAttrib.MyProperty1.Dump(); // 输出:2 methodAttrib.MyProperty2.Dump();
实现说明
- 若你不需要兼容无自定义参数存储属性的第三方Attribute,直接用
GetCustomAttribute拿实例后读属性即可,性能最高 - 若要读取任意Attribute的原始构造入参(不管它有没有把参数存到属性里),就用
CustomAttributeData读取元数据的方案,不需要修改Attribute定义
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

