学习C#高级编程之反射和特性

1.程序时用来处理数据的,文本和特性都是数据,而我们程序本身(类的定义和BLC中的类)这也是数据。

2.有关程序及其类型的数据被称为元数据(metadata),它们保存在程序的程序集中。

3.程序在运行时,可以查看其它程序集或其本身的元数据。一个运行的程序查看本身的元数据或者其他程序集的元数据的行为叫做反射。

MyClass.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _019_反射和特性
{
    class MyClass
    {
        private int id;
        private int age;
        public string Name1 { get; set; }
        public string Name2 { get; set; }
        public string Name3 { get; set; }
        public int number1;
        public int number2;
        public int number3;

        public void Test1()
        {

        }

        public void Test2()
        {

        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Threading.Tasks;

namespace _019_反射和特性
{
    class Program
    {
        static void Main(string[] args)
        {
            //每一个类对于一个type对象,这个type对象存储了这个类 有哪些方法跟哪些数据 哪些成员
            MyClass my = new MyClass();//一个类中的数据是存储在对象中的,但是type对象只存储类的成员
            Type type = my.GetType();//通过对象获取这个对象所属类的Type对象
            Console.WriteLine(type.Name);//获取类的名字
            Console.WriteLine(type.Namespace);//获取所在的命名空间
            Console.WriteLine(type.Assembly);//获取所在的程序集

            FieldInfo[] array = type.GetFields();//只能获取public字段
            foreach(FieldInfo info in array)
            {
                Console.Write(info.Name + " ");
            }

            PropertyInfo[] array2 = type.GetProperties();//获取属性
            foreach(PropertyInfo info in array2)
            {
                Console.Write(info.Name + " ");
            }

            MethodInfo[] array3 = type.GetMethods();//获取方法
            foreach(MethodInfo info in array3)
            {
                Console.Write(info.Name + " ");
            }

            //通过type对象可以获取它对应的类所有的成员(public)
            Console.ReadKey();
        }
    }
}

特性

#define IsTest//定义一个宏

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;

namespace _020_特性
{
    //通过指定熟悉的名字,给属性赋值,这种是命名参数
    [MyTest("简单的特性类",ID = 100)]//当我们使用特性的时候,后面的Attribute不需要写
    class Program
    {
        [Obsolete("这个方法过时了,使用NewMethod代替")]//Obsolete用来表示一个方法被弃用
        //[Obsolete("这个方法过时了,使用NewMethod代替",true)]//true表示不能使用,调用会显示错误
        static void OldMethod()
        {
            Console.WriteLine("Oldmethod");
        }

        static void NewMethod()
        {
            
        }

        [Conditional("IsTest")] //IsTest是一个宏,需要用#define定义,如果未定义调用就不会执行
        static void Test1()
        {
            Console.WriteLine("test1");

        }
        static void Test2()
        {
            Console.WriteLine("Test2");
        }

        //DebuggerStepthrough特性
        //调用者信息特性,可以获取文件名,调用方法和调用行数
        [DebuggerStepThrough]//可以跳过debugger的单步调试 不让进入该方法(当我们确定这个方法没有
        //任何错误的时候,可以使用这个)
        static void PrintOut(string str,[CallerFilePath]string fileName = "",[CallerLineNumber]
        int lineNumber = 0,[CallerMemberName]string methodName = "")
        {
            Console.WriteLine(str);
            Console.WriteLine(fileName);
            Console.WriteLine(lineNumber);
            Console.WriteLine(methodName);
        }

      

        static void Main(string[] args)
        {
            //OldMethod();
            //NewMethod();
            //Test1();
            //Test2();
            //Test1();
            //PrintOut("123");
            Type type = typeof(Program);//通过typeof+类名也可以获取type对象
            object[] array = type.GetCustomAttributes(false);//获取特性类对象数组
            MyTestAttribute mytest = array[0] as MyTestAttribute;
            Console.WriteLine(mytest.Description);
            Console.WriteLine(mytest.ID);
            Console.ReadKey();
        }
    }
}

自定义特性类MyTestAttribute

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _020_特性
{
    //自定义特性类
    //1.特性类的后缀以Attribute结尾
    //2.需要继承自System.Attribute
    //3.一般情况下声明为sealed
    //4.一般情况下特性类用来表示目标结构的一些状态(定义一些字段或熟悉,一般不定义方法)
    [AttributeUsage(AttributeTargets.Class)]//表示该特性类可以应用到的程序结构有哪些
    sealed class MyTestAttribute:System.Attribute
    {
        public string Description { get; set; }
        public string VersionNumber { get; set; }
        public int ID { get; set; }
        public MyTestAttribute(string des)
        {
            this.Description = des;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/kouzhuanjing1849/article/details/81103685