译文链接:https://www.infoworld.com/article/3006630/how-to-work-with-attributes-in-c.html?nsdr=true
Attribute 在 C# 中是一个非常强大的特性,它能够给你的程序集添加元数据信息。
Attribute 实际上是一个对象,它可以与以下元素中的任何一个相关联: 程序集、类、方法、委托、枚举、事件、字段、接口、属性和结构,它会在这些对象上做信息声明,当程序运行之后,你可以通过反射来获取关联到这些对象上的 Attribute 信息,换句话说:你可以通过 Atrribute 向程序集注入一些额外信息,然后在运行时通过反射来获取,attribute 一般由 名字 + 一些可选参数
构成, attribute 名字对应着 atrribute 类。
你可以利用 attribute 去校验你的业务model的正确性, attribute 有两种:内置 + 自定义
, 前者是 .net framework 框架的组成部分,后者需要通过继承 System.Attribute
类来实现自定义。
现在来看看代码怎么写,Obsolete
特性用来标记一个方法是过时的,这个过时的意思是:你不应该再使用这个方法了,未来框架也会将其剔除,目前也存在其替代方案
。其实在第三方框架中有很多这样的例子,下面的代码片段展示了如何在方法顶部使用 Obsolete
特性。
[Obsolete("This method is obsolete...")]
public static void DoSomeWork()
{
}
如果你在程序中调用了这个方法,当你编译代码时,在 Visual Studio 输出窗口中会现在一些警告信息,如下图:
当然,如果你一定要忽视它也是可以的,现在,假如你希望你的开发同事不允许调用这个方法,那如何去限定呢?哈哈,可以使用 Obsolete 的第二个参数,这个参数是可选的,下面是 DoSomeWork()
方法的修改版本,请注意这是一个 Boolean 型参数。
[Obsolete("This method is obsolete...", true)]public static void DoSomeWork(){}
当把 true 给了这个可选参数后,再次编译代码,你会发现代码根本编译不通过,是不是完美的解决了你的问题,是吧!截图如下:
自定义 attribute
这一小节我们来看一下如何去实现自定义的 attribute,要想自定义实现,可以创建一个类并继承 System.Attribute
类即可,如下代码所示:
using System;
public class CustomAttribute : Attribute
{}
要想限定 CustomAttribute 的使用,可以用 AttributeUsage 类去标记,这个类包含了如下属性:ValidOn
,AllowMultiple
,Inherited
等等,这些标记都可以限定 CustomAttribute 的使用。
下面的代码片段展示了 CustomAttribute 的修改版本,这个类使用构造函数去给内部的私有 string 赋值,代码仅仅用于演示目的。
[AttributeUsage(AttributeTargets.All)]public class CustomAttribute : Attribute{private string text;public CustomAttribute(string text){this.Text = text;}public string Text { get => text; set => text = value; }}
当然你也可以按需去指定这些 AttributeTargets,如下代码所示:
[AttributeUsage(AttributeTargets.Class |AttributeTargets.Constructor |AttributeTargets.Field |AttributeTargets.Method |AttributeTargets.Property,AllowMultiple = true)]public class CustomAttribute : Attribute{private string text;public CustomAttribute(string text){this.Text = text;}public string Text { get => text; set => text = value; }}
接下来你可以用反射来获取应用到对象上的所有attributes,代码如下:
static void Main(string[] args){MemberInfo memberInfo = typeof(CustomAttribute);object[] attributes = memberInfo.GetCustomAttributes(true);for (int i = 0, j = attributes.Length; i < j; i++){Console.WriteLine(attributes[i]);}}
接下来我准备将 CustomAttribute 类应用到 下面的 SomeClass 类上。
[CustomAttribute("Hello World...")]
public class SomeClass
{
}
可以着重看下 CustomAttribute 是如何安插在 SomeClass 上的,而且我还传递了一个 Hello World...
字符串给它,下面的代码展示了如何将 CustomAttribute 中的 Text 属性打印出来。
class Program{static void Main(string[] args){MemberInfo memberInfo = typeof(SomeClass);object[] attributes = memberInfo.GetCustomAttributes(true);foreach (object attribute in attributes){CustomAttribute customAttribute = attribute as CustomAttribute;if (customAttribute != null)Console.WriteLine("Text = {0}", customAttribute.Text);elseConsole.WriteLine();}}}[CustomAttribute("Hello World...")]public class SomeClass{}[AttributeUsage(AttributeTargets.Class |AttributeTargets.Constructor |AttributeTargets.Field |AttributeTargets.Method |AttributeTargets.Property,AllowMultiple = true)]public class CustomAttribute : Attribute{private string text;public CustomAttribute(string text){this.Text = text;}public string Text { get => text; set => text = value; }}