• c# 关于反射


    反射的用途大体总结:
    1、使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从程序集中查找类型并创建该类型的实例。CreateInstance
    2、使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其它特定的非全局方法。
    3、使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如public或private)和实现详细信息(如abstract或virtual)等。
    4、使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如public或private)和实现详细信息(如abstratc或virtual)等。
    5、使用FieldInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。
    6、使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。
    7、使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。
    8、使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。
    System.Reflection
    System.Type
    System.Reflection.Assembly

    反射用到的主要类
    System.Type类--通过这个类可以访问任何给定数据类型的信息
    System.Reflection.Assembly类--它可以用于访问给定程序集的信息,或者把这个程序集加载到程序中。

    System.Type类
    System.Type类 对于反射起着核心的作用。但它是一个抽象的基类,Type有与每种数据类型对应的派生类,我们使用这个派生类的对象的方法、字段、属性来查找有关该类型的所有信息

    获取给定类型的Type引用有3中常用方式:
    1、使用typeof运算符
    Type t = typeof(string);
    2、使用对象GetType()方法
    sring s = "lslsl";
    Type t = s.GetType();
    3、还可以使用Type类的静态方法GetType()
    Type t = Type.GetType("System.String");
    在取出Type引用t后我们就可以通过t来探测string类型的结构了

    string n = "";
    Type t = n.GetType();
    foreach(MemberInfo mi in t.GetMembers())
    {
    Console.WriteLine("{0}/{1}",mi.MemberType,mi.Name);
    }

    Type类的属性
    Name数据类型名
    FullName数据类型的完全限定名(包括命名空间名)
    Namespace定义数据类型的命名空间名
    IsAbstract 是否是抽象类型
    IsArray 是否是数组
    IsClass 是否是类
    IsEnum 是否是枚举
    IsPublic 是否是public
    IsSealed 是否是密封类
    IsValueType 是否是值类型

    Type类的方法
    GetConstructor(),GetConstructors()返回ConstructorInfo类型,用于取得该类的构造函数的信息
    GetEvent(),GetEvents() 返回EventInfo类型,用于取得该类的事件的信息
    GetField(),GetFields() 返回FieldInfo类型,用于取得该类的字段(成员变量)的信息
    GetInterface(), GetInterfaces() 返回InterfaceInfo类型,用于取得该类实现的接口信息
    GetMember(), GetMembers() 返回MemberInfo类型,用于取得该类的所有成员信息
    GetMethod(),GetMethods() 返回MethodInfo类型,用于取得该类的方法的信息
    GetProterty(),GetProperties() 返回PropertyInfo类型,用于取得该类的属性的信息
    可以调用这些成员,方式是调用Type的InvokeMember()方法,或者调用MemberInfo,PropertyInfo和其它类的Invoke()方法。

    System.Reflection.Assembly介绍
    Assenbly类可以获得程序集的信息,也可以动态的加载程序集,以及在程序集中查找类型信息,并创建该类型的实例。

    使用Assembly类可以降低程序集之间的耦合,有利于软件结构的合理化
    通过程序集名称返回Assembly对象
    Assembly ass = Assembly.Load("ClassLibrary111");
    通过Dll文件名称返回Assembly对象
    Assembly ass = Assembly.LoadFrom("ClassLibrary111.dll");
    通过Assembly获取程序集类
    Type t = ass.GetType("ClassLibrary111.NewClass");//参数必须是类的全名
    通过Assembly获取程序集的所有类
    Type[] t = ass.GetTypes();//通过程序集的名称反射
    Assembly ass = Assembly.Load("ClassLibrary11");
    Type t = ass.GetType("ClassLibrary111.NewClass");
    object o = Activator.CreateInstance(t, "mantishell", "https://www.baidu.com");
    MethodInfo mi = t.GetMethod("Show");
    mi.Invoke(o, null);
    //通过Dll文件全名反射其中的所有类型
    Assembly assembly = Assembly.LoadFrom("xxx.dll的路径");
    Type[] types = assembly.GetTypes();
    foreach(Type t in types){
    if(t.FullName == "a.b.c"){
    object o = Activator.CreateInstance(t);
    }
    }

    System.Reflection.Assembly使用
    假设要反射一个dll中的类,并且没有引用它(即未知的类型),我们可以像下面操作
    Assembly assembly = Assembly.LoadFile("程序集的绝对路径“);//exe或dll
    object obj = assembly.CreateInstance("类的完全限定名(即包括命名空间)");

    反射当前项目的中的类
    Assembly assembly = Assembly.GetExecutingAssembly();//获取当前程序集
    object obj = assembly.CreateInstance("Reflection.MainClass");
    ((MainClass)obj).Show();
    其中Reflection.MainClass是命名空间+类名的形式

     代码:

    一个person类和一个包含main方法的myApp类

     1 namespace myApp{
     2     public class Person{
     3         public string str;
     4         public int num;
     5 
     6         private string index;
     7 
     8         public string Name{get;set;}
     9         public int Age{get;set;}
    10         public string Index { get => index; set => index = value; }
    11 
    12         public Person(){
    13             System.Console.WriteLine("No Parameter Constructor");
    14         }
    15 
    16         public Person(string str, int num){
    17             this.str = str;
    18             this.num = num;
    19             System.Console.WriteLine("Have Some Parameter Constructor");
    20         }
    21 
    22         public void Show(){
    23             System.Console.WriteLine("Show , name:{0}, Age:{1}", this.Name, this.Age);
    24         }
    25     }
    26 }
    View Code
      1 using System;
      2 using System.Reflection;
      3 
      4 namespace myApp
      5 {
      6     class Program
      7     {
      8         static void Main(string[] args)
      9         {
     10             Type t = typeof(Person);
     11 
     12             #region 获取
     13             /*System.Console.WriteLine("P:{0}", t);//命名空间贾类名
     14 
     15             //获取类中的所有公有字段
     16             FieldInfo[] fis = t.GetFields();
     17             foreach(var item in fis){
     18                 System.Console.WriteLine(item);
     19             }
     20             //获取类中所有的属性
     21             PropertyInfo[] pis = t.GetProperties();
     22             foreach(var item in pis){
     23                 System.Console.WriteLine(item);
     24             }
     25             //构造函数
     26             ConstructorInfo[] cis = t.GetConstructors();
     27             foreach(var item in cis){
     28                 System.Console.WriteLine(item);
     29                 //构造函数的参数列表
     30                 ParameterInfo[] pis2 = item.GetParameters();
     31                 foreach(var item2 in pis2){
     32                     System.Console.WriteLine(item2);
     33                 }
     34             }
     35 
     36             //方法,包括继承的方法
     37             MethodInfo[] mt = t.GetMethods();
     38             foreach(var item in mt){
     39                 System.Console.WriteLine(item);
     40             }*/
     41 
     42             #endregion
     43 
     44             #region 使用构造函数创建实例
     45 
     46             //用构造函数创建一个实例
     47             /*Type[] paramType = new Type[2];
     48             paramType[0] = typeof(string);
     49             paramType[1] = typeof(int);
     50 
     51             //根据指定的参数,获取对应的构造函数
     52             ConstructorInfo ci = t.GetConstructor(paramType);
     53             object[] obj = new Object[] {"Hello", 123};//传递的参数
     54             object person = ci.Invoke(obj);
     55             ((Person)person).Show();//调用方法
     56             */
     57             #endregion
     58 
     59             #region 使用Activator创建实例
     60 
     61             /*object[] obj = new object[]{"Hello", 1};
     62             object person = Activator.CreateInstance(t);//无参构造方法
     63             ((Person)person).Show();
     64 
     65             object person2 = Activator.CreateInstance(t, obj);
     66             ((Person)person).Name = "ddd";
     67             ((Person)person).Show();
     68 
     69             object person3 = Activator.CreateInstance(t, "Hello", 11);
     70             ((Person)person).Show();
     71             */
     72 
     73             #endregion
     74 
     75             #region 使用
     76 
     77             Person person = new Person();
     78             t = person.GetType();
     79 
     80             object obj = Activator.CreateInstance(t);
     81 
     82             FieldInfo f = t.GetField("str");//根据字段名获取字段
     83             f.SetValue(obj, "Hello");//字段赋值
     84 
     85             FieldInfo f2 = t.GetField("num");
     86             f2.SetValue(obj, 12);
     87 
     88             System.Console.WriteLine(f.GetValue(obj));
     89 
     90             PropertyInfo p1 = t.GetProperty("Name");//获取属性
     91             p1.SetValue(obj, "Jimmy", null);//赋值
     92 
     93             PropertyInfo p2 = t.GetProperty("Age");
     94             p2.SetValue(obj, 123, null);
     95             System.Console.WriteLine(p2.GetValue(obj));
     96 
     97             //方法
     98             MethodInfo mi = t.GetMethod("Show");
     99             mi.Invoke(obj, null);
    100 
    101             #endregion
    102         }
    103     }
    104 }
    View Code
  • 相关阅读:
    Visual Studio日志
    选择jQuery的理由
    第三方开发者可将JIT和编译器引入WinRT吗?
    Visual Studio 2012和.NET 4.5已经就绪!
    500TB——Facebook每天收集的数据量
    Netflix开源他们的另一个架构——Eureka
    PhoneGap 2.0 发布
    快速哈希算法破坏了加密的安全性
    Blend for Visual Studio 2012:为Windows 8应用所用的UX工具
    系统中的故障场景建模
  • 原文地址:https://www.cnblogs.com/mantishell/p/12076392.html
Copyright © 2020-2023  润新知