属性(Attribute)是C#中用于向代码元素(如类、方法、属性等)添加元数据的机制。这些元数据可以在编译时或运行时通过反射访问,从而影响编译器或运行时的行为。
属性是继承自 System.Attribute
类的特殊类。它们可以附加到程序集、模块、类、方法、属性、字段、参数等代码元素上。
属性的定义和使用
定义一个属性类时,通常以 Attribute
结尾,并继承自 System.Attribute
。使用时可以省略 Attribute
后缀。
csharp
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class MyCustomAttribute : Attribute
{
public string Description { get; set; }
public MyCustomAttribute(string description)
{
Description = description;
}
}
使用时:
csharp
[MyCustom("This is a class attribute")]
public class MyClass
{
[MyCustom("This is a method attribute")]
public void MyMethod() { }
}
属性的常见应用
-
序列化控制:
-
使用
[Serializable]
标记类为可序列化,或使用[NonSerialized]
标记字段不被序列化。
csharp
[Serializable] public class MyClass { public int Id { get; set; } [NonSerialized] private string SecretData; }
-
-
Web API 路由和验证:
-
在ASP.NET Core中,使用
[HttpGet]
、[HttpPost]
等属性定义路由,使用[Required]
、[StringLength]
等进行数据验证。
csharp
[ApiController] [Route("api/[controller]")] public class MyController : ControllerBase { [HttpGet("{id}")] public IActionResult Get(int id) { return Ok(new { Id = id }); } [HttpPost] public IActionResult Post([FromBody] MyModel model) { if (!ModelState.IsValid) { return BadRequest(ModelState); } return Ok(); } }
-
-
单元测试:
-
在单元测试框架中,使用
[TestClass]
和[TestMethod]
标记测试类和测试方法。
csharp
[TestClass] public class MyTests { [TestMethod] public void TestMethod1() { Assert.AreEqual(1, 1); } }
-
-
依赖注入:
-
使用
[Inject]
或[Dependency]
等属性标记需要注入的依赖。
csharp
public class MyService { [Inject] public IMyDependency Dependency { get; set; } }
-
-
代码分析:
-
使用
[Obsolete]
标记过时的代码,编译器会发出警告或错误。
csharp
[Obsolete("This method is obsolete. Use NewMethod instead.")] public void OldMethod() { } public void NewMethod() { }
-
-
自定义属性:
-
创建自定义属性以添加特定元数据,并在运行时通过反射访问。
csharp
[MyCustom("This is a class attribute")] public class MyClass { [MyCustom("This is a method attribute")] public void MyMethod() { } } // 通过反射获取属性 var attributes = typeof(MyClass).GetCustomAttributes(typeof(MyCustomAttribute), false); foreach (MyCustomAttribute attr in attributes) { Console.WriteLine(attr.Description); }
-
属性的原理
属性本质上是元数据,存储在程序集的元数据表中。编译器在编译时会将属性信息嵌入到程序集中,运行时可以通过反射读取这些信息。
AttributeUsage
属性
AttributeUsage
属性用于指定自定义属性的使用方式,包括:
-
AttributeTargets
:指定属性可以应用的目标(如类、方法等)。 -
AllowMultiple
:是否允许多次应用到同一目标。 -
Inherited
:是否允许派生类继承该属性。
csharp
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class MyCustomAttribute : Attribute
{
public string Description { get; set; }
public MyCustomAttribute(string description)
{
Description = description;
}
}
总结
属性是C#中强大的元数据机制,广泛用于序列化、Web API、单元测试、依赖注入等场景。通过自定义属性,可以为代码添加额外的元数据,并在运行时通过反射访问这些信息,从而实现更灵活和可扩展的设计