C#关于特性Attribute

特性Attribute

什么是特性

特性是一种允许我们向程序的程序集增加元数据的语言结构,它是用于保存程序结构信息的某种特殊类型的

  • 拥有特性的代码程序叫做 目标
  • 获取和使用元数据的代码程序叫做 特性的消费者

编译器获取源代码并从特性中产生元数据,然后把元数据放到程序集中; 
消费者程序 可以获取特性的元数据以及程序中其他组件的元数据,即编译器同时生产和消费特性

使用前置 特性片段 来应用特性,特性片段被方括号包围,方括号中为 特性名 特性的参数列表

我们可以使用 assembly: 和 module: 来设定全局特性,即程序集或块级别,程序集级别的特性一般都要放置在如何命名空间之外,通常放置在 AssemblyInfo.cs 文件中

以上来自原文链接:https://blog.csdn.net/qq_38801354/article/details/79884391

Obsolete

有时候版本更新,旧方法被弃用,可以用Obsolete表示这个方法已被启用

使用方法:

[obsolete(参数1,参数2)] 参数1表示调用时提示的信息,参数2表示是否提示错误

示例代码:

[Obsolete("该方法已过时,可用NewMethod代替",true)]//true表示调用时出现的是错误而不是警告

static void OldMethod()        

{

 Console.WriteLine("旧方法");

}

static void NewMethod()        

{

 Console.WriteLine("新方法");

}

 

Conditional

有时候我们项目未上线前或者测试时需要使用一些测试方法,加上Conditional特性可以帮助我们更好的调试程序。

使用方法:

在最上面添加一个宏定义

#define IsTest

引入命名空间:

using System.Diagnostics

在方法上面加入[Conditional(“IsTest”)]

 

示例代码:

#define IsTest //宏定义,用于测试。注释后相关方法将不可用

 

using System;

using System.Diagnostics;//Conditional用

 

namespace Conditional

{

    class Program

    {

        static void Main(string[] args)

        {

            TestMethod();

            Method();

        }

 

        [Conditional("IsTest")]

        static void TestMethod()

        {

            Console.WriteLine("这是一段测试代码");

        }

 

        static void Method()

        {

            Console.WriteLine("正式代码");

        }

    }

}

TestMethod()就是我们要用于测试的方法,当我们不需要使用这个方法时,只要#define IsTest注释掉,程序运行时就不会跳过TestMethod()的调用。

 

调用信息特性

如果我们需要得到方法的调用者信息,可以使用:

[Caller.......],直接上代码好理解点:

static void Main(string[] args)

{

    string str = "lzx`s File";

    TestMethod(str);

}

 

static void TestMethod(string str,[CallerFilePath] string fileName="",[CallerLineNumber]int lineNumber=0,[CallerMemberName]string methodName="")

{

    Console.WriteLine(str);

    Console.WriteLine(fileName);

    Console.WriteLine(lineNumber);

    Console.WriteLine(methodName);

}

输出:

 C#关于特性Attribute

 

 

DebuggerStepThrough特性

这个相对简单,只要在方法上面加入[DebuggerStepThrough]特性,在调试时就会跳过该方法的单步调试,但我们确定这个方法没有错误的时候,就可以使用这个特性简化我们的调试过程。

比如上面的TestMethod方法:

[DebuggerStepThrough]//调试时跳过该方法内的单步调试

static void TestMethod(string str,[CallerFilePath] string fileName="",[CallerLineNumber]int lineNumber=0,[CallerMemberName]string methodName="")

{

    Console.WriteLine(str);

    Console.WriteLine(fileName);

    Console.WriteLine(lineNumber);

    Console.WriteLine(methodName);

}

 

其他特性

 C#关于特性Attribute

 

 

自定义特性Attribute

特性其实就是一种特殊的类,所以自定义特性其实也是一种继承自Attribute的类。以下是它的一些特点:

  1. 特性类的后缀Attribute结尾
  2. 需要继承system.Attribute
  3. 一般情况下声明为sealed
  4. 一般情况下 特性类是用来表示目标结构的一些状态(定义一些字段或者属性,一般不定义方法)

举个例子,我们自定义了一个MyTestAttribute特性

sealed class MyTestAttribute:Attribute

{

    public string Desription { get; set; }//特性的描述

    public string VersionNumber { get; set; }//版本

    public int ID { get; set; }

 

    //特性的使用可以简单理解为每次使用特性类,这里我们简单定义了以下这个构造函数。当然可以不定义构造函数,这样系统就会调用预定义的无参无实现的构造函数

    //public MyTestAttribute(string des)

    //{

    //    this.Desription = des;

    //}

}

 

指定Program为MyTestAttribute特性:

[MyTest(Desription = "lzx", ID = 1, VersionNumber = "ss")]//使用匿名参数赋值

class Program

{

......

}

 

此时我们就可以在Main中使用Type取得特性的成员了:

Program pro = new Program();

Type type = pro.GetType();

object[] array = type.GetCustomAttributes(false);//两个注意点:一是使用Object类

//二是GetCustomAttributes(),这个方法是使用了反射来搜索该类所具有的所有的特性;输入的参数,false表示不去搜索其父类中的所具有的特性

foreach(MyTestAttribute my in array)

{

Console.WriteLine(my.ID);

}

 

还有一种方法,可以直接获取特性中的某个成员:

var myTestID = (type.GetCustomAttributes(TypeOf(MyTestAttribute),false)[0] as MyTestAttribute).ID;

这种方法适用于已知成员的索引

C#关于特性Attribute

上一篇:windows快捷键学习


下一篇:C# --------- 获取时间差