一、概念:

1、什么是特性(Attribute)?

  特性(Attribute)是用于在运行时传递程序中各种元素(比如类、方法、结构、枚举、组件等)的行为信息的声明性标签。

  • 在一个元素(如类和属性,方法等等)上可以使用一个或多个特性进行修饰。
  • 特性可以拥有参数。
  • 程序可使用反射来检查自己的元数据或其他程序中的元数据。
2、特性示例
[Serializable]
  [XmlRoot("MyClass")]
  public class MyClass
  {
      
      public int id;
  
      [NonSerialized]
      public string name;
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

二、特性的使用

1、预定义特性(Net 框架提供了三种预定义特性):
(1)AttributeUsage

  限制特性对元素内的什么类型有效。仅可用在特性声明上,也就是说只能在Attribute的派生类上生效。

namespace System
  {
      [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)]
      public sealed class SerializableAttribute : Attribute
      {
          public SerializableAttribute();
      }
  }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

  ① 属性

名字

意义

ValidOn

此位置参数指定指示的属性可放置到的程序元素。 枚举中列出了可以放置属性的所有可能元素的集合  AttributeTargets 。 可以  AttributeTargets 使用按位 "或" 运算组合几个值,以获取所需的有效程序元素组合。

Inherited

此命名参数指定所指示的属性是否可由派生类和重写成员继承。

AllowMultiple

此命名参数指定是否可为给定的程序元素多次指定指定的属性。

Targets 枚举值 官网文档

(2)Conditional

  用来进行条件编译

  ① 示例( 官网文档):

#define CONDITION1
#define CONDITION2
using System;
using System.Diagnostics;

class Test
{
    static void Main()
    {
        Console.WriteLine("调用方法1");
        Method1(3);
        Console.WriteLine("调用方法2");
        Method2();

        Console.WriteLine("使用Debug类");
        Debug.Listeners.Add(new ConsoleTraceListener());
        Debug.WriteLine("DEBUG已定义");
    }

    [Conditional("CONDITION1")]
    public static void Method1(int x)
    {
        Console.WriteLine("CONDITION1已定义");
    }
    // 多个
    [Conditional("CONDITION1"), Conditional("CONDITION2")]
    public static void Method2()
    {
        Console.WriteLine("CONDITION1或CONDITION2已定义");
    }
}

/*
When compiled as shown, the application (named ConsoleApp)
produces the following output.

Calling Method1
CONDITION1 is defined
Calling Method2
CONDITION1 or CONDITION2 is defined
Using the Debug class
DEBUG is defined
*/
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
(3)Obsolete

  用来标记过时的元素,如:方法。

  ① 属性:

名字

意义

message

描述项目为什么过时以及该替代使用什么

iserror

如果该值为 true,编译器应把该项目的使用当作一个错误;如果该值为 false,编译器生成一个警告。默认值是 false。

  ② 示例:

using System;
public class MyClass
{
   [Obsolete("不要使用OldMethod,而是使用NewMethod!", true)]
   static void OldMethod()
   {
      Console.WriteLine("这是旧方法!");
   }
   static void NewMethod()
   {
      Console.WriteLine("这是新方法!");
   }
   public static void Main()
   {
      OldMethod();
   }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
2、自定义特性:(摘自:官方文档: 创建自定义特性)

  创建并使用自定义特性的四个步骤:

  • 声明自定义特性(继承System.Attribute)
  • 构建自定义特性
  • 在目标程序元素上应用自定义特性
  • 通过反射访问特性(见C#-反射)
(1)声明并构建自定义特性
[System.AttributeUsage(System.AttributeTargets.Class |
                       System.AttributeTargets.Struct,
                       AllowMultiple = true)  // Multiuse attribute.
]
public class AuthorAttribute : System.Attribute
{
    string Name;
    public double Version;

    public AuthorAttribute(string name)
    {
        Name = name;

        // Default value.
        Version = 1.0;
    }

    public string GetName() => Name;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
(2)使用
[Author("P. Ackerman"), Author("R. Koch", Version = 2.0)]
public class ThirdClass
{
    // ...
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
3、多个特性使用

(1)多[]标识:

[特性1(参数...)]
[特性2(参数...)]
  • 1.
  • 2.

(2)使用,隔开:

[特性1(参数...),特性2(参数...)]
  • 1.

作者:꧁执笔小白꧂