C# 特性(Attribute)
本章节围绕以下七个方面来系统讲解C# 的特性(Attribute),能够全面深入了解 C# 的特性(Attribute)。
一、什么是 Attribute(特性)?
在 C# 中,特性(Attribute) 是一种用于向程序的元素(如类、方法、属性、字段等)添加元数据的机制。
它不会直接影响程序运行逻辑,而是可以通过 反射 在运行时读取,用于控制行为、配置信息、实现框架支持等。
简单说:Attribute 是告诉程序“这是一些额外的信息”,供运行时或框架使用。
📘 官方文档:
https://learn.microsoft.com/zh-cn/dotnet/csharp/programming-guide/concepts/attributes/
二、Attribute 的使用场景
| 场景 | 说明 |
|---|---|
| 标注序列化规则 | 如 [JsonProperty("name")] 控制序列化字段 |
| 控制反射行为 | 控制是否参与反射、标识方法用途 |
| 声明性编程 | 比如 [Obsolete] 标记方法过时 |
| ASP.NET 配置 | 如 [HttpGet]、[Route("api/test")] |
| 自定义验证 | 表单模型验证 [Required], [MaxLength] 等 |
| 单元测试 | 如 [TestMethod], [Fact], [Theory] |
三、Attribute 的语法基础
✅ 使用系统内置 Attribute
[Obsolete("请不要再使用这个方法")]
public void OldMethod()
{
// 旧逻辑
}
🔍 ObsoleteAttribute 会在编译时发出警告/错误。
✅ 特性基本语法结构
[AttributeName(positional_argument, named_argument=value)]
命名规范是:特性类以 Attribute 结尾,但使用时可以省略。
四、自定义 Attribute
1. 定义特性类
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class MyNoteAttribute : Attribute
{
public string Note { get; }
public MyNoteAttribute(string note)
{
Note = note;
}
}
2. 应用特性
[MyNote("这个类用于演示")]
public class DemoClass
{
[MyNote("调用前请验证")]
public void DoSomething() { }
}
3. 使用反射读取特性
var type = typeof(DemoClass);
var attributes = type.GetCustomAttributes(typeof(MyNoteAttribute), false);
foreach (MyNoteAttribute attr in attributes)
{
Console.WriteLine(attr.Note);
}
五、实战案例:基于特性 + 反射实现接口权限控制
场景:我们为 API 方法标记角色权限特性,并在执行前校验。
✅ 1. 定义特性类
[AttributeUsage(AttributeTargets.Method)]
public class RoleAttribute : Attribute
{
public string RequiredRole { get; }
public RoleAttribute(string role)
{
RequiredRole = role;
}
}
✅ 2. 在方法中标注
public class UserController
{
[Role("Admin")]
public void DeleteUser() { }
[Role("User")]
public void ViewProfile() { }
}
✅ 3. 运行时判断权限
public void ExecuteWithRoleCheck(string methodName, string userRole)
{
var method = typeof(UserController).GetMethod(methodName);
var attr = method.GetCustomAttribute<RoleAttribute>();
if (attr != null && attr.RequiredRole != userRole)
{
throw new UnauthorizedAccessException("权限不足");
}
method.Invoke(new UserController(), null);
}
六、常用系统内置 Attribute
| 特性 | 说明 |
|---|---|
[Obsolete] | 标记不推荐使用的方法 |
[Serializable] | 标记可以序列化的类 |
[NonSerialized] | 标记字段不参与序列化 |
[DllImport] | 用于调用非托管 DLL |
[Conditional] | 根据条件编译 |
[DefaultValue] | 设置默认值 |
[Description] | 添加描述信息,常用于 UI 或配置 |
[Required], [Range] | ASP.NET 表单验证特性 |
👉 详见官方文档:https://learn.microsoft.com/zh-cn/dotnet/standard/attributes/
七、最佳实践与注意事项
- 不要滥用特性:仅在需要表达元信息或运行时动态处理的情况下使用。
- 合理使用 AttributeUsage 控制特性应用范围:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
- 结合反射谨慎处理性能问题,尤其是在循环体中频繁反射。
- 多用于声明性编程和元数据驱动的框架(如 ASP.NET、EF Core、XUnit)。
相关权威参考链接
- C# Attributes – Microsoft Docs(官方)
- Attribute 类 – System 命名空间
- AttributeUsageAttribute 类文档
- Stack Overflow – 使用 Attribute 的最佳实践
总结
C# 的 Attribute 为我们提供了非常强大的 声明性元数据编程能力,可以让代码结构更清晰、功能更强大,特别适用于以下场景:
- 框架构建(比如 ASP.NET MVC)
- 序列化控制(如 JSON、XML)
- 动态行为驱动(如权限、日志、路由)
- 代码分析工具与注解
更多详细内容请关注其他相关文章!