在 c# 中,并没有一个专门的“获取特性的接口”(即没有类似 igetattribute 这样的接口供你实现或调用)。
获取特性(attributes)是通过 反射(reflection) 机制完成的,主要依赖以下两个核心类/方法:
system.attribute类:提供了静态方法来获取特性。system.reflection命名空间下的类型:如type,methodinfo,propertyinfo等,它们提供了实例方法getcustomattributes。
以下是获取特性的三种主要方式:
1. 使用attribute.getcustomattribute(推荐用于获取单个)
这是最传统且语义清晰的方法,适用于当你确定只需要获取一个特定类型的特性时。
- 位置:
system命名空间 - 特点:如果找到返回该特性实例,找不到返回
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<myattribute>(type);
2. 使用memberinfo.getcustomattributes(推荐用于获取多个)
这是 type, methodinfo, propertyinfo 等反射对象的实例方法。适用于需要获取所有特性,或者不确定是否有多个同名特性的情况。
- 位置:
system.reflection命名空间 - 特点:返回一个数组 (
object[]或t[])。
using system;
using system.reflection;
using system.linq;
type type = typeof(myclass);
// 获取该类型上所有的 myattribute 实例
var attrs = type.getcustomattributes<myattribute>(inherit: true).toarray();
foreach (var attr in attrs)
{
console.writeline(attr.description);
}
// 如果不指定泛型,返回 object[]
var allattrs = type.getcustomattributes(inherit: true); 3. 使用icustomattributeprovider接口 (底层机制)
虽然你通常不直接使用它,但值得了解的是,所有可以应用特性的元素(如 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);
关键参数说明:inherit
在调用 getcustomattributes 时,通常会看到一个 bool inherit 参数:
true: 不仅检查当前元素,还会沿着继承链向上查找基类或基接口上的特性(前提是特性定义时[attributeusage(inherited = true)])。false: 只检查当前元素直接声明的特性。
现代 c# 模式匹配写法 (c# 7.0+)
在实际开发中,结合 is 模式匹配可以让代码更简洁:
var method = typeof(myclass).getmethod("dowork");
// 检查并获取
if (method.getcustomattribute<obsoleteattribute>() is obsoleteattribute obsattr)
{
console.writeline($"该方法已过时: {obsattr.message}");
}
// 或者检查是否存在任意特性
if (method.getcustomattributes<authorizationattribute>().any())
{
// 执行授权逻辑
}总结
| 需求 | 推荐方法 | 返回类型 |
|---|---|---|
| 获取单个特定特性 | attribute.getcustomattribute<t>(member) | t (找不到为 null) |
| 获取所有特定特性 | member.getcustomattributes<t>() | ienumerable<t> |
| 获取所有特性(不限类型) | member.getcustomattributes() | object[] |
| 底层接口 | icustomattributeprovider | object[] |
注意:为了性能考虑,.net 6 及更高版本引入了 system.reflection.customattributeextensions,上述泛型方法大多扩展自此类,性能优于旧的非泛型方法。
到此这篇关于c# 获取特性的接口的实现的文章就介绍到这了,更多相关c# 获取特性接口内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论