c#进阶-10.特性

概念

特性本质上是个类,利用特性类为元数据添加额外信息,之后通过反射来获取这些信息。

用法:

#define func
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Diagnostics;

namespace 特性
{
    //知识点4 限制自定义特性的范围
    //参数一:AttributeTargets用于类、变量还是方法,用|隔开
    //参数二:AllowMultiple是否可以为一个类添加多个特性
    //参数三:Inherited是否可以让派生类和重写成员继承
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Field, AllowMultiple = true, Inherited = false)]
    //知识点2 自定义特性
    class MyCustomAttribute : Attribute
    {
        public string str;

        public MyCustomAttribute(string str)
        {
            this.str = str;
        }
        public void TestFunc()
        {
            Console.WriteLine("特性的方法");
        }
    }

    #region 知识3 特性的使用
    //基本语法:
    //[特性名(参数列表)]
    //本质上是调用特性类的构造函数,写在类、函数、变量上一行

    [MyCustom("自己的特性类")]//受AttributeUsage中的AllowMultiple影响
    [MyCustom("自己的特性类")]//特性名后缀Attribute系统自动省略
    class MyClass
    {
        [MyCustom("特性成员变量")]
        public int value;
        //[MyCustom("特性成员函数")]
        public void TestFunc(int a)
        {

        }
    }
    #endregion
    #region 知识5  系统自带特性 过时特性
    //Obsolete,提示该方法已过时
    class MyTest2
    {
        //第一个参数为提示语句
        //第二个参数为true则调用时报错,false则警告
        [Obsolete("该方法已过时",false)]
        public void oldSpeak()
        {

        }        
    }
    #endregion
    #region 知识6 系统自带特性 调用者信息特性
    //一般用在try catch中的catch打印错误信息
    //需引入using System.Runtime.CompilerServices;
    //CallerFilePath为文件路径,CallerLineNumber为哪一行调用,CallerMemberName哪个函数调用
    class MyTest6
    {
        public void SpeakCaller(string str,[CallerFilePath]string filename="",
            [CallerLineNumber]int line=0,[CallerMemberName]string methodname="")
        {
            Console.WriteLine(str);
            Console.WriteLine("调用文件路径:"+ filename);
            Console.WriteLine("调用行:" + line);
            Console.WriteLine("调用方法名:" + methodname);
        }
    }
    #endregion
    #region 知识8 系统自带特性 外部dll包特性
    //用于调用c或c++的dll包中的方法,不做介绍

    #endregion
    class Program
    {
        #region 知识点7 系统自带特性 条件编译特性
        //条件编译特性Conditional
        //与define配合,需引入
        //有定义func,函数Func才会被编译
        [Conditional("func")]
        static void Func()
        {
            Console.WriteLine("func");
            
        }
        #endregion
        static void Main(string[] args)
        {
            #region 特性的使用
            MyClass mc = new MyClass();
            Type t = mc.GetType();
            //判断该类是否使用了某个特性
            //参数一:特性类型 参数二:是否搜索父亲有这个特性
            if(t.IsDefined(typeof(MyCustomAttribute),false))
            {
                Console.WriteLine("该类型应用了MyCustom特性");
            }
            //获取Type元数据的所有特性
            //GetCustomAttributes里的参数和上面意思一样
            object[] array = t.GetCustomAttributes(true);
            for(int i=0;i<array.Length;i++)
            {
                if(array[i] is MyCustomAttribute)
                {
                    Console.WriteLine((array[i] as MyCustomAttribute).str);//str=自己的特性类
                    (array[i] as MyCustomAttribute).TestFunc();                   
                }
            }
            MyTest2 myTest2 = new MyTest2();
            myTest2.oldSpeak();
            MyTest6 myTest6 = new MyTest6();
            myTest6.SpeakCaller("abc");

            Func();
            #endregion
            
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值