在 C# 编程中,特性(Attribute)是一种非常重要的工具,它可以为程序元素(类、方法、属性、字段等)添加元数据,以便在运行时或编译时提供额外的信息和行为控制。本文将带你从基础概念到自定义特性全面了解 C# 特性。
一、特性(Attribute)概述
特性是一种声明性标签,用于向程序元素添加元数据信息。它的语法非常直观:
[attribute(positional_parameters, name_parameter = value, ...)]
element
- positional_parameters:必需的信息,通过构造函数传入。
- name_parameter:可选的信息,通过属性赋值指定。
特性本质上是一个类,继承自 System.Attribute,可以在运行时通过反射读取。
二、预定义特性(Predefined Attribute)
.NET 框架提供了一些常用的预定义特性,主要包括:
1. AttributeUsage
AttributeUsage 用于指定特性可以应用到哪些程序元素,并可以设置是否可多次使用以及是否可继承。
语法:
[AttributeUsage(
validOn,
AllowMultiple = allowmultiple,
Inherited = inherited
)]
validOn:指定特性可应用的目标(如类、方法、字段等),可使用AttributeTargets枚举组合。默认值:AttributeTargets.All。AllowMultiple:是否允许多次使用该特性,默认false。Inherited:是否允许子类继承,默认false。
示例:
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{
}
2. Conditional
Conditional 特性用于条件编译方法。当指定的预处理符号未定义时,方法调用会被忽略。
语法:
[Conditional("DEBUG")]
示例:
#define DEBUG
using System;
using System.Diagnostics;
public class MyClass
{
[Conditional("DEBUG")]
public static void Message(string msg)
{
Console.WriteLine(msg);
}
}
class Test
{
static void Function1()
{
MyClass.Message("In Function 1.");
Function2();
}
static void Function2()
{
MyClass.Message("In Function 2.");
}
public static void Main()
{
MyClass.Message("In Main function.");
Function1();
Console.ReadKey();
}
}
输出结果:
In Main function.
In Function 1.
In Function 2.
如果删除 #define DEBUG,以上消息将不会打印。
3. Obsolete
Obsolete 特性用于标记不推荐使用的代码,编译器会显示警告或错误信息。
语法:
[Obsolete("message", isError)]
message:描述为什么过时及替代方案。isError:是否将过时使用视为编译错误,默认false(警告)。
示例:
using System;
public class MyClass
{
[Obsolete("Don't use OldMethod, use NewMethod instead", true)]
static void OldMethod()
{
Console.WriteLine("This is the old method");
}
static void NewMethod()
{
Console.WriteLine("This is the new method");
}
public static void Main()
{
OldMethod(); // 编译器报错
}
}
编译器将报错提示:Don't use OldMethod, use NewMethod instead。
三、自定义特性(Custom Attribute)
.NET 允许开发者自定义特性,以存储元数据信息并在运行时读取。自定义特性通常包含以下四步:
- 声明自定义特性
- 构建自定义特性类
- 在程序元素上应用特性
- 使用反射访问特性信息
1. 声明自定义特性
自定义特性必须继承自 System.Attribute:
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Method |
AttributeTargets.Property,
AllowMultiple = true)]
public class DeBugInfo : System.Attribute
{
}
2. 构建自定义特性
我们定义一个 DeBugInfo 特性来存储以下信息:
- Bug 编号(必需)
- 开发者名字(必需)
- 最后一次审查日期(必需)
- 备注信息(可选)
示例代码:
public class DeBugInfo : Attribute
{
private int bugNo;
private string developer;
private string lastReview;
public string Message { get; set; }
public DeBugInfo(int bg, string dev, string d)
{
bugNo = bg;
developer = dev;
lastReview = d;
}
public int BugNo => bugNo;
public string Developer => developer;
public string LastReview => lastReview;
}
3. 应用自定义特性
将特性放在类、方法或字段之前即可:
[DeBugInfo(45, "Zara Ali", "12/8/2012", Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012", Message = "Unused variable")]
class Rectangle
{
protected double length;
protected double width;
public Rectangle(double l, double w)
{
length = l;
width = w;
}
[DeBugInfo(55, "Zara Ali", "19/10/2012", Message = "Return type mismatch")]
public double GetArea()
{
return length * width;
}
[DeBugInfo(56, "Zara Ali", "19/10/2012")]
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width: {0}", width);
Console.WriteLine("Area: {0}", GetArea());
}
}
4. 使用反射访问特性
在下一篇文章中,我们将结合 Reflection 演示如何读取类、方法、属性上的自定义特性信息,实现运行时元数据获取。
四、总结
本文介绍了 C# 中 特性的概念、预定义特性和自定义特性 的使用方法:
- 特性可以添加元数据信息,提高代码可读性和可维护性。
- 预定义特性如
AttributeUsage、Conditional、Obsolete提供了常用功能。 - 自定义特性可根据项目需求灵活扩展,并可结合反射在运行时读取。
特性是 C# 高级特性之一,熟练掌握后能让代码更智能、更易维护。
👋 关注我!持续分享 C# 实战技巧、代码示例 & 技术干货
详解:预定义与自定义特性应用教程&spm=1001.2101.3001.5002&articleId=158768692&d=1&t=3&u=1d57c47377d14c598591aee9e720ff8b)
260

被折叠的 条评论
为什么被折叠?



