.NET Core 实战 [No.94~98] 特性
特性是一种比较特殊的类,通常作为代码对象的附加部分,用于向 CLR 提供一些补充信息。
特性在项目中应用很广,比如 Web 服务(ASMX) 中一般都会用到如下特性:
csharp
[WebMethod(Description = "", EnableSession = false)]
[ScriptMethod(UseHttpGet = false)]
再比如 MVC 项目中的路由、权限、验证等:
csharp
[Route("blog/{id=}")]
[AllowAnonymous]
[Required]
特性具有以下特征:
- 从
Attribute
类派生 - 类名一般以 Attribute 结尾。这是一个约定,建议开发者遵守这一约定。
- 必须在自定义的特性类上应用
AttributeUsageAttribute
。
csharp
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = true)]
class DemoAttribute : Attribute
{
public string Description { get; set; }
}
AttributeUsage
默认的构造函数有一个枚举参数 validOn,可以指定特性的应用目标,支持枚举的组合。
另外 AttributeUsage
特性还有一个属性 AllowMultiple,默认值为 false,表示是否支持在同一个对象上应用复数个特性的实例。
特性本质上是一个类,也有构造函数。当使用无参构造函数时,可以省略 ()
。
csharp
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = true)]
class DemoAttribute : Attribute
{
public DemoAttribute()
{
}
public DemoAttribute(string description)
{
Description = description;
}
public string Description { get; set; }
}
可以通过 GetCustomAttribute<T>()
方法获取对应属性、方法等上面应用的特性。
这些扩展方法位于 System.Reflection.CustomAttributeExtensions 类中。
Test.cs
csharp
class Test
{
[Demo("姓名")]
public string Name { get; set; }
}
csharp
var type = typeof(Test);
var prop = type.GetProperty("Name", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
if (prop == null) return;
var att = prop.GetCustomAttribute<DemoAttribute>();
Console.WriteLine($"The description of Test.Name is \"{att.Description}\" .");
// The description of Test.Name is "姓名" .
方法的参数上也是可以应用特性的,如:
csharp
public void AddBlog([FromBody] BlogInfo blogInfo) {
// do something
}
另外,特性也可以应用于方法的返回值,这需要在特性定义的 AttributeUsage
上添加 AttributeTargets.ReturnValue
目标。
csharp
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Method | AttributeTargets.ReturnValue, AllowMultiple = true)]
class DemoAttribute : Attribute
{
// ...
}
csharp
[return: Demo]
static string SaySomething() => "Hello";
参考:《.NET Core 实战:手把手教你掌握 380 个精彩案例》 -- 周家安 著