反射
文本较差,具体请看代码,如有错误,欢迎指出
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; } }
方法:注意将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(); }
上一篇: Python遍历指定文件及文件夹的方法