发布于2026-07-06 阅读(0)
扫一扫,手机访问
C#里其实并没有一个专门的“获取特性的接口”——别找了,没有类似IGetAttribute这样的东西可以直接调用。获取特性(Attributes)这件事,靠的是反射(Reflection)机制,核心依赖两个方向:
System.Attribute 类提供的静态方法System.Reflection 命名空间下的 Type、MethodInfo、PropertyInfo 等类型,它们都提供了 GetCustomAttributes 实例方法那具体怎么操作?三种主流方式,按场景选就行。

这是最传统、最直观的方法。什么时候用?当你明确只要一个特性,不想啰嗦的时候。调用后如果找到就返回特性实例,找不到就返回 null。值得注意的是,如果同一个元素上标记了多个同类型特性(并且 AllowMultiple=true),这个方法只会返回第一个。
using System;
using System.Reflection;
// 假设 MyClass 上有一个 [MyAttribute]
Type type = typeof(MyClass);
// 获取单个特性
var attr = (MyAttribute)Attribute.GetCustomAttribute(type, typeof(MyAttribute));
if (attr != null)
{
Console.WriteLine(attr.Description);
}
泛型版本(.NET Core / .NET 5+ 更推荐):
// 语法更简洁,无需手动强制转换 var attr = Attribute.GetCustomAttribute(type);
这是 Type、MethodInfo、PropertyInfo 等反射对象的实例方法。适合需要获取全部特性,或者不确定到底有几个同名特性的情况。返回值是一个数组(object[] 或泛型版本 T[])。
using System; using System.Reflection; using System.Linq; Type type = typeof(MyClass); // 获取该类型上所有的 MyAttribute 实例 var attrs = type.GetCustomAttributes(inherit: true).ToArray(); foreach (var attr in attrs) { Console.WriteLine(attr.Description); } // 如果不指定泛型,返回的是 object[] var allAttrs = type.GetCustomAttributes(inherit: true);
虽然平时几乎不直接用它,但了解底层逻辑总没坏处。所有可以应用特性的元素——Type、Assembly、MethodInfo 等——都实现了 System.Reflection.ICustomAttributeProvider 接口。它定义了两个核心方法,前面说的 GetCustomAttributes 本质上就是调用的这里:
object[] GetCustomAttributes(bool inherit)object[] GetCustomAttributes(Type attributeType, bool inherit)// Type 类实现了 ICustomAttributeProvider ICustomAttributeProvider provider = typeof(MyClass); var attrs = provider.GetCustomAttributes(typeof(MyAttribute), true);
这种写法通常在开发底层反射框架时才会用到,日常开发不必这么绕。
调用 GetCustomAttributes 时经常会看到 bool inherit 这个参数。区别在于:
true:不仅检查当前元素,还会沿着继承链向上查找基类或基接口上的特性(前提是特性定义时设置了 [AttributeUsage(Inherited = true)])。false:只看当前元素自己声明的特性,不管父类。实际开发中,配合 is 模式匹配可以让代码干净很多:
var method = typeof(MyClass).GetMethod("DoWork");
// 检查并获取
if (method.GetCustomAttribute() is ObsoleteAttribute obsAttr)
{
Console.WriteLine($"该方法已过时: {obsAttr.Message}");
}
// 或者检查是否存在任意特性
if (method.GetCustomAttributes().Any())
{
// 执行授权逻辑
}
这种方式在编码时非常顺手,尤其适合做条件判断和后续处理。
| 需求 | 推荐方法 | 返回类型 |
|---|---|---|
| 获取单个特定特性 | Attribute.GetCustomAttribute | T(找不到为 null) |
| 获取所有特定特性 | member.GetCustomAttributes | IEnumerable |
| 获取所有特性(不限类型) | member.GetCustomAttributes() | object[] |
| 底层接口 | ICustomAttributeProvider | object[] |
最后多说一句:.NET 6 及更高版本引入了 System.Reflection.CustomAttributeExtensions,上面那些泛型方法大多数扩展自此类,性能上比旧的非泛型方法更优,日常开发建议优先使用泛型版本。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8