商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > c#获取特性的接口的实现

c#获取特性的接口的实现

  发布于2026-07-06 阅读(0)

扫一扫,手机访问

C#里其实并没有一个专门的“获取特性的接口”——别找了,没有类似IGetAttribute这样的东西可以直接调用。获取特性(Attributes)这件事,靠的是反射(Reflection)机制,核心依赖两个方向:

  • System.Attribute 类提供的静态方法
  • System.Reflection 命名空间下的 TypeMethodInfoPropertyInfo 等类型,它们都提供了 GetCustomAttributes 实例方法

那具体怎么操作?三种主流方式,按场景选就行。

c#获取特性的接口的实现

1. 使用 Attribute.GetCustomAttribute —— 获取单个特性,首选

这是最传统、最直观的方法。什么时候用?当你明确只要一个特性,不想啰嗦的时候。调用后如果找到就返回特性实例,找不到就返回 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);

2. 使用 MemberInfo.GetCustomAttributes —— 获取多个,更灵活

这是 TypeMethodInfoPropertyInfo 等反射对象的实例方法。适合需要获取全部特性,或者不确定到底有几个同名特性的情况。返回值是一个数组(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);

3. 认识 ICustomAttributeProvider 接口 —— 底层机制

虽然平时几乎不直接用它,但了解底层逻辑总没坏处。所有可以应用特性的元素——TypeAssemblyMethodInfo 等——都实现了 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);

这种写法通常在开发底层反射框架时才会用到,日常开发不必这么绕。

关键参数:inherit

调用 GetCustomAttributes 时经常会看到 bool inherit 这个参数。区别在于:

  • true:不仅检查当前元素,还会沿着继承链向上查找基类或基接口上的特性(前提是特性定义时设置了 [AttributeUsage(Inherited = true)])。
  • false:只看当前元素自己声明的特性,不管父类。

现代 C# 简洁写法(C# 7.0+)

实际开发中,配合 is 模式匹配可以让代码干净很多:

var method = typeof(MyClass).GetMethod("DoWork");

// 检查并获取
if (method.GetCustomAttribute() is ObsoleteAttribute obsAttr)
{
    Console.WriteLine($"该方法已过时: {obsAttr.Message}");
}

// 或者检查是否存在任意特性
if (method.GetCustomAttributes().Any())
{
    // 执行授权逻辑
}

这种方式在编码时非常顺手,尤其适合做条件判断和后续处理。

总结一下

需求推荐方法返回类型
获取单个特定特性Attribute.GetCustomAttribute(member)T(找不到为 null)
获取所有特定特性member.GetCustomAttributes()IEnumerable
获取所有特性(不限类型)member.GetCustomAttributes()object[]
底层接口ICustomAttributeProviderobject[]

最后多说一句:.NET 6 及更高版本引入了 System.Reflection.CustomAttributeExtensions,上面那些泛型方法大多数扩展自此类,性能上比旧的非泛型方法更优,日常开发建议优先使用泛型版本。

本文转载于:https://www.jb51.net/program/36346555s.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注