zoukankan      html  css  js  c++  java
  • 反射

     文本较差,具体请看代码,如有错误,欢迎指出

    1.反射生成类步骤:
    加载DLL(【Assembly】.Load,LoadFile,LoadFrom),LoadFrom实质上也是调用Load,但是可以指定全路径
    获取格式
    实例化
    object DB=Activator.CreateInstance(Tp);【属于Object类,无法调用方法】
    [类型] ODB=(类型)DB;【需要强制转换后才可以使用】



    2.调用方法
      4.1 构造函数:

    object DB=Activator.CreateInstance(Tp);
      4.1.1 调用私有构造函数:
      object DB=Activator.CreateInstance(Tp,true);

    4.1.2 生成泛型构造函数:若反射的类为DBHelper<T,W,X>,则
    Type Tp=As.GetType("ConsoleApp1.SayHello`2");【包含2个占位符,需要写入】
    Type NewTp=Tp.MakeGenericType(typeof(string), typeof(int));【重新生成一个新的类型,需要将类型赋给泛型然后生成该新的类型】
    object DB=Activator.CreateInstance(NewTp);【使用新类型创建对象】

    4.1.3 调用有参数的构造函数:构造函数为DBHelper(int x,string y){};DBHelper(string X){};【两个构造函数】
    Assembly As=Assembly.Load("Ruanmou.DB.Sqlserver");
    Type Tp=As.GetType("Ruanmou.DB.Sqlserver.DBHelper");
    object DB1=Activator.CreateInstance(Tp,new object{223,"Abc"});【传递参数调用对应的构造函数,会根据传递的参数的类型调用对应的构造函数】
    object DB2=Activator.CreateInstance(Tp,new object{"Abc"});【传递的参数必须跟已经有的构造函数的位置和类型一致,否则会报错】、

    4.2 方法:(DB1 是已经实例化的类,且未强制转换的Object类型 Tp为获取的类型)
    4.2.1 无参数实例化方法 :Show1(){};
    MethodInfo method=Tp.GetMethod("Show1");
    method.Invoke(DB1,null);

    4.2.2 有参数实例化方法 :Show2(int x){};
    MethodInfo method=Tp.GetMethod("Show2");
    method.Invoke(DB1,new object{123});

    4.2.3 有参数静态方法 :static Show3(int x){};
    MethodInfo method=Tp.GetMethod("Show3");
    method.Invoke(null,new object{123});【可以传递实例,但是不会调用】

    4.2.3 多个重载方法 : Show4(){};Show4(int x){};Show4(string y){};Show4(int x,string y){};Show4(string y,int x){};
    MethodInfo method1=Tp.GetMethod("Show3",new Type{});【调用无参重载】
    MethodInfo method2=Tp.GetMethod("Show3",new Type{typeof(int)});【调用带一个Int重载】
    MethodInfo method3=Tp.GetMethod("Show3",new Type{typeof(string)});
    MethodInfo method4=Tp.GetMethod("Show3",new Type{typeof(int),typeof(string)});
    MethodInfo method5=Tp.GetMethod("Show3",new Type{typeof(string),typeof(int)});

    method1.Invoke(DB1);【无参数不必传递参数】
    method2.Invoke(DB1,new object{123});【有参数的必须传递对应参数】
    method3.Invoke(DB1,new object{"abc"});【】
    method4.Invoke(DB1,new object{123,"abc"});【参数的类型,位置都必须一致】
    method5.Invoke(DB1,new object{"abc",123});【】

    4.2.4 调用私有方法: Private Show5 (){};
    MethodInfo method=Tp.GetMethod("Show5",BingDingFlags.NonPublic|BingDingFlags.Instance);【获取私有属性必须两个都写上】
    method.Invoke(DB1);

    4.2.5 调用泛型方法: Show6<T>(T a){};
    MethodInfo method=Tp.GetMethod("Show6");
    Newmethod = method.MakeGenericMethod(typeof(string));【设置泛型为string】
    Newmethod.Invoke(DB1,new object{"abc"});

    4.3 属性和字段
    4.3.1 获取和设置属性(DB1 是已经实例化的类,且未强制转换的Object类型 Tp为获取的类型)
    foreach(var item in Tp.GetProperties())
    {
    item.GetValue();
    if(item.Name=="Name")
    {
    item.SetValue(DB1,"abc");
    }
    if(item.Name=="ID")
    {
    item.SetValue(DB1,100001);
    }
    }
    var Property=Tp.GetProperty("属性名"[,BingDingFlags.NonPublic|BingDingFlags.Instance]) 【获取指定的属性名,加后面内容可以获取私有属性】
    var Filed=Tp.GetFiled("字段名"[,BingDingFlags.NonPublic|BingDingFlags.Instance]) 【获取指定的字段名,加后面内容可以获取私有属性】

    类:

      public class Hello
        {
            public string Name{ get;  set; } 
            string Sex { get;  set; } 
    
            public void PublicSayHello()
            {
                Console.WriteLine(string.Format(@"无参公有方法:{0} {1}! Hello! ", Sex, Name));
            }
    
            public void PublicSayHello(int tip)
            {
                Console.WriteLine(string.Format(@"带参公有方法 tip{2}:{0} {1}! Hello! ", Sex, Name,tip));
            }
    
            private void PrivateSayHello()
            {
                Console.WriteLine(string.Format(@"无参私有方法 :{0} {1}! Hello! ", Sex, Name));
            }
    
            public void PublicGenericSayHello<G>(G tip)
            {
                Console.WriteLine(string.Format(@"带参泛型公有方法 tip{2}:{0} {1}! Hello! ", Sex, Name, tip));
            }
    
    
            private Hello(string name,string sex="PrivateSex") { Name = name;Sex = sex; }
    
            public Hello() { Sex = "PublicSex"; }//因为定义了一个有参构造函数,所以需要
    
            public Hello(string name) { Name = name; Sex = "PublicSex"; }//因为定义了一个有参构造函数,所以需要
        }
    
        public class SayHello<T,W>
        {
      
            T LastName { get; set; }
            T FirstName { get; set; }
            W Age { get; set; }
    
            public void PublicSayHello()
            {
                Console.WriteLine(string.Format(@"无参公有方法:{0} {1},you are {2}!! ", FirstName, LastName, Age));
            }
    
         
    
            public SayHello(T firstName,T lastName, W age) { FirstName = firstName; LastName = lastName; Age = age; }
        }
    View Code

     方法:注意将DLL的路径,完全限定的类型替换

    Assembly ass = Assembly.Load("ConsoleApp1");//获取bin下的dll
                Assembly Loadass = Assembly.LoadFrom(@"E:laijiWebApplication1ConsoleApp1inDebug
    etcoreapp2.0ConsoleApp1.dll");//获取路径下的dll
                Assembly Thisass = Assembly.GetExecutingAssembly();//获取本程序集的dll
                {
                    Type T1 = ass.GetType("ConsoleApp1.Hello");
                    Type T2 = Loadass.GetType("ConsoleApp1.Hello");
                    Type T3 = Thisass.GetType("ConsoleApp1.Hello");
                    Type T4 = typeof(Hello);//直接获取类型
    
    
                    object[] Parms = new object[2];//参数列表,必须和构造函数的参数对应
                    Parms[0] = "ObjectName";
                    Parms[1] = "ObjectSex";
    
                    var data1 = Activator.CreateInstance(T1) as Hello;//未进行转换无法调用下面的方法和赋值,调用无参公有构造函数
                    data1.Name = "TestMan";
                    data1.PublicSayHello();
    
                    var data2 = Activator.CreateInstance(T1,new object[] { "PublicParmsName"}) as Hello;//未进行转换无法调用下面的方法和赋值,调用无参公有构造函数
                    data2.PublicSayHello();
    
                    //注意,使用的构造方法不同
                    var PrivateData = ass.CreateInstance(T3.FullName, true, BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic, null, Parms, null, null) as Hello;//调用私有有参构造函数
                    PrivateData.PublicSayHello();
    
                    //调用方法
                    {
                        Console.WriteLine("********************调用方法****************");
                        MethodInfo PublicMethod1 = T1.GetMethod("PublicSayHello", new Type[] { });//调用公有方法,如果方法没有重载可以省略new Type[] { }
                        PublicMethod1.Invoke(PrivateData, null);//null为参数列表,必须一一对应
    
                        MethodInfo PublicMethod2 = T1.GetMethod("PublicSayHello", new Type[] { typeof(int) });//调用公有方法,如果有重载,要在后面加上参数类型列表,必须一一对应
                        PublicMethod2.Invoke(PrivateData, new object[] { 1 });//null为参数列表,必须一一对应
    
                        MethodInfo PrivateMethod1 = T1.GetMethod("PrivateSayHello", BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { }, null);//调用私有方法
                        PrivateMethod1.Invoke(PrivateData, null);
    
                        MethodInfo PublicMethod3 = T1.GetMethod("PublicGenericSayHello");//调用泛型方法
                        MethodInfo Newmethod = PublicMethod3.MakeGenericMethod(typeof(int));
                        Newmethod.Invoke(PrivateData, new object[] { 1 });
                    }
    
                    //修改属性,字段
                    {
                        Console.WriteLine("********************修改属性,字段****************");
                        //1.遍历获取,仅能获取公有属性
                        foreach (var item in T1.GetProperties())
                        {
                            item.SetValue(PrivateData, "SetValueForeach");//设置属性的值,为了方便,将所有属性的值都设为SetValueForeach
                        }
                        PrivateData.PublicSayHello();
    
                        //2.获取指定属性
                        PropertyInfo Pt1 = T1.GetProperty("Name");//公有属性
                        Pt1.SetValue(PrivateData, "SetValueUsePropertyName");
                        PrivateData.PublicSayHello();
    
                        PropertyInfo Pt2 = T1.GetProperty("Sex",BindingFlags.Instance|BindingFlags.NonPublic);//私有属性
                        Pt2.SetValue(PrivateData, "SetValueUsePropertyNameBySex");
                        PrivateData.PublicSayHello();
    
                        //字段同属性,仅将Property换成Field
                    }
                }
                {
                    Console.WriteLine("********************调用泛型构造函数****************");
                    //泛型构造函数
                    Type Tp = ass.GetType("ConsoleApp1.SayHello`2");//后面要带占位符`2
                    Type NewType = Tp.MakeGenericType(typeof(string), typeof(int));//需要新建一个泛型类型
                    var Data = Activator.CreateInstance(NewType, new object[] {"FFN","LLN",18 }) as SayHello<string,int>;//使用泛型类型创建实例
                    Data.PublicSayHello();
                }
    View Code


























  • 相关阅读:
    CentOS 7 和centos6切换图形界面和多用户界面
    centos6.8下安装elasticsearch
    一个xib钟多个Cell
    iOS frame从导航栏下面开始
    Xcode 移除(卸载)插件
    iOS9 HTTP传输安全
    pch头文件
    真机调试---打包6plus出现问题
    Xcode 添加类前缀
    iOS 状态栏黑色背景白色字体
  • 原文地址:https://www.cnblogs.com/GZNETLGN/p/8916533.html
Copyright © 2011-2022 走看看