【C#】特性 Attribute

特性

概念:特性是一种允许我们向程序的程序集添加元数据的语言结构,是用于保存程序结构信息的某种特殊类型的类。特性提供功能强大的方法以将声明信息与C#代码(类型、方法、属性等)相关联。特性与程序实体关联后,即可在运行时使用反射查询特性信息。特性的目的是告诉编译器把程序结构的某组元数据嵌入程序集中,可以放置在几乎所有的声明中(类、变量、函数等)。

可以理解为特性是一个特殊的继承自Attribute的类,用来为元数据添加信息,然后通过反射来获取这些信息。

自定义特性

语法

class MyCustomAttribute : Attribute
{
    //特性成员
    public string info;

    public MyCustomAttribute(string info) 
    {
        this.info = info;
    }

    public void TestFun()
    {
        Console.WriteLine("这是特性中的方法");
    }
}

特性的使用

本质上是调用特性类的构造函数。

位置:类、函数、变量的上一行,表示他们具有该特性。

语法:

[特姓名(参数列表)]

[MyCustom("这是一个自定义类")]
class Test
{
    [MyCustom("这是一个成员变量")]
    public string info;

    [MyCustom("这是一个成员函数")]
    public void TestFun([MyCustom("函数参数")]int i)
    {

    }
}
internal class Program
{
    static void Main(string[] args)
    {
        //特性的使用
        Test test = new Test();
        //三种获得Type的方式
        Type t = typeof(Test);
        t = Type.GetType("L21_特性.Test");
        t = test.GetType();

        //使用一:用来判断是否使用了某个特性;
        //参数一:特性的Type类型;参数二:是否搜索继承链(属性和事件忽略此参数)
        if (t.IsDefined(typeof(MyCustomAttribute), false))
        {
            Console.WriteLine("该类型应用了MyCustom特性");
        }

        //使用二:获取元数据中的所有特性,可以执行方法。
        object[] objects = t.GetCustomAttributes(true); 
        for (int i = 0; i < objects.Length; i++)
        {
            if (objects[i] is MyCustomAttribute) 
            {
                Console.WriteLine((objects[i] as MyCustomAttribute).info);
                (objects[i] as MyCustomAttribute).TestFun();
            }
        }
    }
}

限制自定义特性的使用范围

为自定义的特性类添加特性就可以先限制特性类的使用范围。

语法

//参数一:AttributeTargets —— 特性能够使用的位置
//参数二:AllowMultiple —— 是否允许多个特性实例用在同一目标上
//参数三:Inherited —— 特性是否能被派生类和重写成员继承
//此处写法是通过属性来初始化
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct,AllowMultiple = true,Inherited = true)]
public class MyCustomAttribute2:Attribute
{

}

系统自带特性——过时特性

关键字:obsolete

使用:用于提示用户使用的方法等成员已经过时,建议使用新方法。

一般用于函数。

实例

class Test1 
{
    //参数一:提示的内容
    //参数二:true —— 使用该方法时直接报错;false —— 使用该方法时警告
    [Obsolete ("这个方法已经过时了,请使用speak方法",false)]
    public void OldSpeak() { }
    public void Speak() { }
}

系统自带特性——调用者信息特性

作为函数参数的特性,可以得到具体的信息,通过函数打印出来。

需要应用命名空间。

一般用于作为函数参数的特性,或者try catch的catch中,用于查错误的位置。

[CallerFilePath] —— 哪个文件调用

[CallerLineNumber] —— 哪一行调用

[CallerMemberName] —— 哪个函数调用

实例

    class Test1 
    {
        public void Speak2(string str1, [CallerFilePath] string filePath = "", [CallerLineNumber] int line = 0,
            [CallerMemberName]string target = "") 
        {
            Console.WriteLine(str1);
            Console.WriteLine(filePath);
            Console.WriteLine(line);
            Console.WriteLine(target);
        }
    }
            static void Main(string[] args)
        {
            //系统自带特性——调用者信息特性
            Test1 test1 = new Test1();
            test1.Speak2("hahahah");
        }

系统自带特性——条件编译特性

语法[Conditional(“define定义的符号”)]

使用:主要用于需要调试的代码上,和预处理指令#define配合使用。

当函数的条件编译特性参数与define定义的符号相同时,可以执行该函数,否则不会执行。

系统自带特性——外部dll包函数特性

语法[DllImport(“文件名或路径名”)]

作用:一般用来调用C或C++的Dll包写好的方法

需要引用命名空间:using System.Runtime.InteropServices;

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值