欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

反射

程序员文章站 2022-07-08 19:27:03
文本较差,具体请看代码,如有错误,欢迎指出 1.反射生成类步骤: 加载DLL(【Assembly】.Load,LoadFile,LoadFrom),LoadFrom实质上也是调用Load,但是可以指定全路径 获取格式 实例化 object DB=Activator.CreateInstance(Tp ......

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

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:\laiji\WebApplication1\ConsoleApp1\bin\Debug\netcoreapp2.0\ConsoleApp1.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