• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

C#:反射和特性

武飞扬头像
爱卷的小Zang
帮助1

一、反射概念与Type类

1、程序在运行过程中,可以查看其他程序集或本身程序集中的元数据的行为叫做反射。

程序集:项目中所有代码以及嵌入式资源的集合。

元数据:我们编写的程序以及程序内数据。

2、反射的作用:

通过反射可以读取程序集(.dll、.exe)中代码内容

可以根据字符串类名,来动态创建类的对象

可以动态获取对象中的信息(方法、属性、字段)

可以根据字符串方法名称来调用执行

3、反射的常用类

1) Type类:设计用来包含类型的特性,可以获取程序使用的类型的信息。(可以获得一个类包含的成 员与方法。)

2)命名空间 using System.Reflection;

  1.  
    //实体人员类
  2.  
    public class Person{
  3.  
       public string Name;
  4.  
       public int Age;
  5.  
       private int _ID;
  6.  
       
  7.  
       //属性
  8.  
       public int ID{
  9.  
           get{return _ID;}
  10.  
           set{_ID=value;}
  11.  
      }
  12.  
       
  13.  
       public DisplayID(){
  14.  
           Console.WriteLine(_ID);
  15.  
      }
  16.  
       
  17.  
       public DisplayName(){
  18.  
           Console.WriteLine(Name);
  19.  
      }
  20.  
       
  21.  
       public DisplayAge(){
  22.  
           Console.WriteLine(Age);
  23.  
      }
  24.  
    }
  25.  
  26.  
     
  27.  
    using System.Threading.Tasks; //反射的命名空间
  28.  
    class Demo(){
  29.  
       public void Test1(){
  30.  
           Person per =new Person();
  31.  
           Type tyPersonObj=per.GetType(); //反射定义
  32.  
           
  33.  
           //显示类的名称
  34.  
           Console.WriteLine(tyPersonObj.Name);
  35.  
           //显示类所属的命名空间
  36.  
           Console.WriteLine(tyPersonObj.Namespace);
  37.  
           //显示类所属的程序集
  38.  
           Console.WriteLine(tyPersonObj.Assembly);
  39.  
           //获取类是否为公共、密封、私有
  40.  
           Console.WriteLine(tyPersonObj.IsPublic);//True
  41.  
           Console.WriteLine(tyPersonObj.IsSealed);//False
  42.  
           Console.WriteLine(tyPersonObj.IsPrimitive);//False
  43.  
           //获取字段GetFields()方法
  44.  
           FieldInfo[] ingoArray=tyPersonObj.GetFields();
  45.  
           Foreach(FieldInfo item in ingoArray){
  46.  
               Console.WriteLine(item.Name);
  47.  
          }
  48.  
           //获取属性GetProperties()方法
  49.  
            PropertyInfo[] propArray=tyPersonObj.GetProperties();
  50.  
           Foreach(PropertyInfo item in propArray){
  51.  
               Console.WriteLine(item.Name);
  52.  
          }
  53.  
           //获取方法GetMethods()方法
  54.  
            MethodInfo[] metgodArray=tyPersonObj.GetMethods();
  55.  
           Foreach(MethodInfo item in metgodArray){
  56.  
               Console.WriteLine(item.Name);
  57.  
          }
  58.  
      }
  59.  
       static void Main(string[] args){
  60.  
           Demo obj=new Demo();
  61.  
           obj.Test1();
  62.  
      }
  63.  
    }
学新通

二、程序集Assembly与动态调用

1) Assembly类:得到一个程序集中的反射信息

2)使用反射技术,来动态调用

缺点:运行速度慢

优点:可以使得类对象之间的调用关系在“运行期”进行低耦合调用,可以随着配置文件的改变进行改变。

3)程序集中的两种存在方式

*.dll形式存在的程序集(不能直接运行,是“类库”)

*.exe的程序集,可以点击直接运行

如何加载程序集:

Assembly.Load();//不推荐使用

Assembly.LoadFrom(“程序集的完整路径名称”);

  1.  
    //学习Assembly程序集
  2.  
    using System.Reflection;
  3.  
    class Demo{
  4.  
       public void Test1(){
  5.  
           //通过路径直接得到程序集的对象
  6.  
           Assembly assObj=Assembly.LoadFrom(@"E:\System.dll");
  7.  
           //通过程序及,得到程序集中所有的类
  8.  
           Type[] typArray=assObj.GetTypes();
  9.  
           foreach(Type item in typArray){
  10.  
               Console.WriteLine(item.Name);
  11.  
          }
  12.  
           //根据类名与方法名(字符串),动态调用
  13.  
           Type type=assObj.GetType("类名字符串");//包含命名空间的类名
  14.  
           //根据type创建对象
  15.  
           Object obj=Activator.CreateInstance(type);//动态调用类的无参构造方法
  16.  
           //获得方法信息
  17.  
          //Type[] typeArrayWuthPara={type(int)};//重载有参数确定方法重载中有参数
  18.  
           MethodInfo method=type.GetMethod("方法名称字符串");//如果需要重载,则需要在后面添加一个新 //的参数new Type[0],表示重载无参,重 //载有参则调用新定义的Type数组名 //typeArrayWuthPara
  19.  
           //调用有参时添加的语句
  20.  
           //object[] objArray=new object[1];
  21.  
           //object[0]=参数;
  22.  
           //调用方法
  23.  
           method.Invoke(obj,null);//null表示没有参数,如果调用有参方法,null需要换成object数组名
  24.  
      }
  25.  
       static void Main(string[] args){
  26.  
           Demo obj=new Dmeo();
  27.  
           Obj.Test1();
  28.  
      }
  29.  
    }
学新通

反射调用私有方法与属性

  1.  
    class Person{
  2.  
       private int _ID;
  3.  
       //属性
  4.  
       public int ID{
  5.  
           get{return _ID;}
  6.  
           set{_ID=value;}
  7.  
      }
  8.  
       public void DisplayPrivate(){
  9.  
           Console.WriteLine("person类,私有方法,一般情况不可能调用");
  10.  
      }
  11.  
    }
  12.  
  13.  
    using System.Reflection;
  14.  
    class Demo{
  15.  
       //调用私有方法
  16.  
       public void Test1(){
  17.  
           string strClassName="Person";
  18.  
           string strMethodName="DisplayPrivate";
  19.  
           Assembly assObj=Assembly.LoadFrom(strClassName);
  20.  
      //根据类名与方法名(字符串),动态调用
  21.  
      Type type=assObj.GetType("类名字符串");//包含命名空间的类名
  22.  
      //根据type创建对象
  23.  
      Object obj=Activator.CreateInstance(type);//动态调用类的无参构造方法
  24.  
      MethodInfo method=
  25.  
               type.GetMethod("strMethodName",BindingFlags.NonPublic|BindingFlags.Instance);
  26.  
      method.Invoke(obj,null);
  27.  
      }
  28.  
       //调用属性
  29.  
       public void Test2(){
  30.  
           string strClassName="Person";//类的名称
  31.  
           string strPropertydName="ID";//属性的名称
  32.  
           Assembly assObj=Assembly.LoadFrom(strClassName);
  33.  
      //根据类名与方法名(字符串),动态调用
  34.  
      Type type=assObj.GetType("类名字符串");//包含命名空间的类名
  35.  
      //根据type创建对象
  36.  
      Object obj=Activator.CreateInstance(type);//动态调用类的无参构造方法
  37.  
           //获得属性
  38.  
           PropertyInfo prop=type.Getproperty(strPropertydName);
  39.  
           //设置属性
  40.  
           prop.SetValue(obj,100);
  41.  
           //得到属性值
  42.  
           string result=prop.GetValue(obj,null).ToString();
  43.  
           Console.WriteLine(result);
  44.  
      }
  45.  
       static void Main(string[] args){
  46.  
           Demo obj=new Dmeo();
  47.  
           Obj.Test1();
  48.  
           Obj.Test2();
  49.  
      }
  50.  
    }
学新通

三、Type深入方法

bool IsAssignableFrom(Type c) //用来判断一个类或接口是否另一个类的父类或接口

bool IsInstanceOfType(object o)//判读对象o 是否是当前类(或者子类)的实例,或者实现本接口

bool IsSubclassOf(Type c)//判断当前类是否为类c (参数)的子类

  1.  
    //父类
  2.  
    public class Men{}
  3.  
    //子类
  4.  
    public class ZhangSan:Men,ICanSpeak{}
  5.  
    //普通类 无继承
  6.  
    public class Dog{}
  7.  
    //接口
  8.  
    interface ICanSpeak{}
  9.  
    //学习Type更多的方法
  10.  
    //1.判断一个类是否为(参数)类的父类或者接口
  11.  
    //
  12.  
    //
  13.  
    //
  14.  
    using System.Reflection;
  15.  
    class Demo{
  16.  
       //bool IsAssignableFrom(Type c) //用来判断一个类或接口是否另一个类的父类或接口
  17.  
       public void Test1(){
  18.  
           Type typeMen=typeof(Men);
  19.  
           Type typeZhangSan=typeof(ZhangSan);
  20.  
           Type typeDog=typeof(Dog);
  21.  
           Type typeICanSpeak==typeof(ICanSpeak);
  22.  
           //判断Men是ZhangSan的父类吗
  23.  
           Console.WriteLine(typeMen.IsAssignableFrom(typeZhangSan));//true
  24.  
           //判断Men是Dog的父类吗
  25.  
           Console.WriteLine(typeMen.IsAssignableFrom(typeDog));//False
  26.  
           //判断ICanSpeak是否为ZhangSan的接口
  27.  
           Console.WriteLine(typeICanSpeak.IsAssignableFrom(typeZhangSan));//true
  28.  
           //判断ICanSpeak是否为Dog的接口
  29.  
           Console.WriteLine(typeICanSpeak.IsAssignableFrom(Dog));//false
  30.  
      }
  31.  
       //bool IsInstanceOfType(object o)//判读对象o 是否是当前类(或者子类)的实例,或者实现本接口
  32.  
       public void Test2(){
  33.  
           Type typeMen=typeof(Men);
  34.  
    Type typeICanSpeak==typeof(ICanSpeak);
  35.  
           Men MenObj=new Men();
  36.  
           ZhangSan zhangsanObj=new ZhangSan();
  37.  
           Dog dogObj=new Dog();
  38.  
           //typeMen是MenObj的实例吗?
  39.  
           Console.WriteLine(typeMen.IsInstanceOfType(MenObj));//T
  40.  
           Console.WriteLine(typeMen.IsInstanceOfType(zhangsanObj));//T
  41.  
           Console.WriteLine(typeMen.IsInstanceOfType(dogObj));//F
  42.  
           Console.WriteLine(typeICanSpeak.IsInstanceOfType(zhangsanObj));//T
  43.  
           Console.WriteLine(typeICanSpeak.IsInstanceOfType(MenObj));//F
  44.  
      }
  45.  
       //bool IsSubclassOf(Type c)//判断当前类是否为类c (参数)的子类
  46.  
       public void Test3(){
  47.  
    Type typeMen=typeof(Men);
  48.  
           Type typeZhangSan=typeof(ZhangSan);
  49.  
           Type typeDog=typeof(Dog);
  50.  
    Console.WriteLine(typeZhangSan.IsSubclassOf(typeMen)); //T
  51.  
           Console.WriteLine(typeDog.IsSubclassOf(typeMen));//F
  52.  
      }
  53.  
       static void Main(string[] args){
  54.  
           Demo obj=new Demo();
  55.  
           obj.Test1();
  56.  
           obj.Test2();
  57.  
           obj.Test3();
  58.  
      }
  59.  
    }
学新通

四、预定义特性Attribute

1.特性(Attribute)是一种允许我们向程序集增加元数据的语言结构,提供了一种将声明性信息与代码关联起来的途径。

2.Obsolete特性将过时的方法与类标注为“过时”(过期)的,且在编译时,显示警告信息。

3.Conditional特性一般用于程序开发过程中的“测试方法”的编写。测试阶段定义“测试的宏”,发布商业版本,则取消宏即可。

  1.  
    /*
  2.  
    学习特性
  3.  
    一:系统特性
  4.  
    1:Obsolete特性(即:过时特性)
  5.  
    2:Conditional特性
  6.  
    3:Serializable 声明结构可以被序列化
  7.  
    4:NonSerialized 声明结构不可以被序列化
  8.  
    5:DLLImport 声明是非托管代码实现的
  9.  
    二、自定义特性
  10.  
    三、条件编译
  11.  
    1.特性Conditional 适用条件:针对方法
  12.  
    2.使用"预编译”指令 #if debug  
  13.  
    表达式
  14.  
    #else
  15.  
    表达式
  16.  
    #endif
  17.  
    */
  18.  
    #define OnlyTest //定义一个宏,表示允许Conditional特性标识的测试方法允许
  19.  
    #define debug //定义一个宏,表示调试阶段debug允许运行,但else不允许允许
  20.  
    using System;
  21.  
    using System.Collections.Generic;
  22.  
    using System.Linq;
  23.  
    using System.Text;
  24.  
    using System.Therading.Tasks;
  25.  
    using System.Reflection;//反射的命名空间
  26.  
    using System.Diagnostics;//Conditional特性的命名空间,Obsolete不受影响
  27.  
    namespace 学习特性{
  28.  
       class Demo1{
  29.  
           
  30.  
            //学习Obsolete如果加参数True,旧方法不可用,会引发错误,不加则默认false仅提醒自定义的字符串
  31.  
          [Obsolete("该方法已过时,请用对应的NewMethod进行替换",true)]
  32.  
           public void OldMethod(){
  33.  
               Console.WriteLine("这是旧的方法");
  34.  
          }
  35.  
           public void NewMethod(){
  36.  
                Console.WriteLine("这是新的方法");
  37.  
          }
  38.  
           public void Test1(){
  39.  
               //OldMethod();
  40.  
               NewMethod();
  41.  
          }
  42.  
           
  43.  
           //学习Conditional ,条件执行,默认不执行
  44.  
          [Conditional("OnlyTest")]
  45.  
           public void TestMethod(){
  46.  
               Console.WriteLine("这是测试方法");
  47.  
          }
  48.  
           public void Method1(){
  49.  
               Console.WriteLine("这是方法1");
  50.  
          }
  51.  
           public void Method2(){
  52.  
               Console.WriteLine("这是方法2");
  53.  
          }
  54.  
           //条件编译
  55.  
           public void Test3(){
  56.  
               Console.WriteLine("这是条件编译");
  57.  
               Console.WriteLine("aaa");
  58.  
    #if debug
  59.  
               Console.WriteLine("bbb");
  60.  
    #else
  61.  
               Console.WriteLine("ccc");
  62.  
    #endif
  63.  
               Console.WriteLine("ddd");
  64.  
          }
  65.  
           public void Test2(){
  66.  
               TestMethod();
  67.  
               Method2;
  68.  
               TestMethod();
  69.  
               Method1;
  70.  
               TestMethod();
  71.  
               Method1;
  72.  
               Method2;
  73.  
               Method1;
  74.  
          }
  75.  
           static void Main(string[] args){
  76.  
               Demo1 obj=new Demo1();
  77.  
               obj.Test1();
  78.  
               obj.Test2();
  79.  
               obj.Test3();
  80.  
          }
  81.  
      }
  82.  
    }
学新通

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhggbbig
系列文章
更多 icon
同类精品
更多 icon
继续加载