在 C# 中,特性(Attribute)是一种给代码添加 额外信息(元数据)的机制。它不会直接改变代码逻辑,而是为类、方法、属性、字段等附加说明,供编译器、运行时、框架或程序员读取和使用。
简单理解:
特性 = 给代码贴标签,让程序知道这段代码有什么特殊说明。
例如:
cs
[Obsolete("这个方法已经过时,请使用NewMethod")]
public void OldMethod()
{
}
这里 [Obsolete] 就是一个特性,它告诉编译器:
这个方法已经废弃,调用时提醒开发者。
一、为什么需要特性?
假设没有特性:
cs
public class User
{
public string Name;
public int Age;
}
程序不知道:
- Name 是否必须填写?
- Age 是否需要验证?
- 这个类是否需要序列化?
- 是否需要映射数据库?
- 是否需要参与权限控制?
如果使用特性:
cs
public class User
{
[Required]
public string Name { get; set; }
[Range(0,120)]
public int Age { get; set; }
}
框架看到:
Name → 必填
Age → 范围0~120
然后自动执行验证。
二、特性的基本语法
1. 特性写法
cs
[特性名称]
public class MyClass
{
}
例如:
cs
[Serializable]
public class Person
{
}
2. 多个特性
cs
[Serializable]
[Obsolete]
public class Person
{
}
也可以:
cs
[Serializable, Obsolete]
public class Person
{
}
三、C# 常用内置特性
1. Obsolete(过时提醒)
用于标记废弃代码。
例如:
cs
public class Calculator
{
[Obsolete]
public int Add(int a,int b)
{
return a+b;
}
}
调用:
cs
Calculator c=new Calculator();
c.Add(1,2);
提示:
Add方法已经过时
强制报错:
cs
[Obsolete("请使用AddNew",true)]
public int Add(int a,int b)
{
return a+b;
}
第二个参数:
false 警告
true 错误
2. Serializable(序列化)
表示对象可以转换为二进制数据。
cs
[Serializable]
public class Student
{
public string Name;
public int Age;
}
表示:
Student对象
|
↓
二进制数据
3. Conditional(条件编译)
控制代码是否执行。
cs
#define DEBUG
class Test
{
[Conditional("DEBUG")]
public void Log()
{
Console.WriteLine("测试日志");
}
}
如果:
#define DEBUG
存在:
执行。
否则:
方法调用会被忽略。
4. AttributeUsage
用于限制自定义特性使用范围。
例如:
cs
[AttributeUsage(AttributeTargets.Class)]
public class MyAttribute:Attribute
{
}
表示:
只能用于:
cs
[My]
class Person
{
}
不能:
cs
[My]
void Test()
{
}
四、自定义特性(重点)
实际开发中大量使用。
例如:
创建一个:
作者信息特性
第一步:继承 Attribute
cs
public class AuthorAttribute:Attribute
{
}
规定:
所有特性必须继承:
System.Attribute
第二步:添加属性
cs
public class AuthorAttribute:Attribute
{
public string Name {get;set;}
public string Date {get;set;}
}
第三步:使用
cs
[Author(Name="张三",Date="2026")]
public class Book
{
}
五、读取特性(反射)
特性本身不会自动执行。
需要:
Reflection(反射)
例如:
cs
var type=typeof(Book);
var attrs=type.GetCustomAttributes();
foreach(var attr in attrs)
{
Console.WriteLine(attr);
}
输出:
cs
AuthorAttribute
读取具体信息:
cs
AuthorAttribute author =
(AuthorAttribute)Attribute.GetCustomAttribute(
typeof(Book),
typeof(AuthorAttribute)
);
Console.WriteLine(author.Name);
结果:
张三
六、特性参数类型
特性只能接受:
允许:
✅ 基本类型
cs
int
string
bool
double
✅ 枚举
enum Level
{
Low,
High
}
使用:
[My(Level.High)]
✅ Type类型
[Service(typeof(User))]
不能:
❌ 对象
new User()
❌ List
List<string>
七、特性的实际应用
1. ASP.NET Core 路由
例如:
cs
[HttpGet]
public IActionResult GetUser()
{
}
作用:
告诉框架:
这个方法处理GET请求
2. 数据验证
cs
public class User
{
[Required]
public string Name {get;set;}
[EmailAddress]
public string Email {get;set;}
}
框架自动验证。
3. ORM数据库映射
例如:
cs
public class User
{
[Key]
public int Id {get;set;}
[Column("user_name")]
public string Name {get;set;}
}
告诉 ORM:
Id 是主键
Name对应数据库字段 user_name
4. JSON序列化
cs
public class User
{
[JsonIgnore]
public string Password {get;set;}
}
结果:
{
"Name":"Tom"
}
Password不会输出。
八、特性执行流程
完整过程:
源代码
↓
[Attribute]
↓
编译器保存元数据
↓
程序集 DLL
↓
反射读取
↓
框架执行对应功能
九、特性 vs 接口
很多初学者容易混淆。
接口:
表示:
你必须拥有某种能力
例如:
cs
interface IFly
{
void Fly();
}
飞机:
class Plane:IFly
{
}
特性:
表示:
给你添加说明
例如:
[Flying]
class Plane
{
}
区别:
| 接口 | 特性 | |
|---|---|---|
| 作用 | 约束行为 | 添加信息 |
| 是否必须实现方法 | 是 | 否 |
| 运行时读取 | 少 | 经常 |
| 典型用途 | 多态 | 框架配置 |
十、企业开发常见特性体系
学习 C# 后期必须掌握:
基础
Attribute
AttributeUsage
Reflection
Web开发
cs
[ApiController]
[Route]
[HttpGet]
[Authorize]
数据库
cs
[Key]
[Table]
[Column]
[ForeignKey]
序列化
[JsonProperty]
[JsonIgnore]
[Serializable]
AOP编程
例如:
cs
[Log]
[Transaction]
[Cache]
自动实现:
调用前记录日志
执行事务
缓存结果