反射
反射用到的主要类:
System.Type 类–通过这个类可以访问任何给定数据类型的信息。
System.Reflection.Assembly类–它可以用于访问给定程序集的信息,或者把这个程序集加载到程序中。
System.Type类:System.Type 类对于反射起着核心的作用。但它是一个抽象的基类,Type有与每种数据类型对应的派生类,我们使用这个派生类的对象的方法、字段、属性来查找有关该类型的所有信息。
新建一个NewClass类来测试反射
class NewClass
{
public string a;
public int b;
public string Name { get; set; }
public int Age { get; set; }
public NewClass(string m, int n)
{
a = m;
b = n;
}
public NewClass()
{
Console.WriteLine("调用构造函数");
}
public void Show()
{
Console.WriteLine($"生成一个对象a{a}b{b}名字{this.Name}年龄{this.Age}");
}
}
测试代码:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("一、查看类中的构造方法:");
#region 查看类中的构造方法
NewClass nc1 = new NewClass();
Type t1 = nc1.GetType();
ConstructorInfo[] ci1 = t1.GetConstructors();
foreach (var item in ci1)
{
Console.WriteLine("count");
ParameterInfo[] pi = item.GetParameters();
foreach (ParameterInfo p in pi)
{
Console.Write(p.ParameterType.ToString() + " " + p.Name + ",");
}
Console.WriteLine("");
}
Console.WriteLine("----------------------------------------------------");
#endregion
#region 用构造函数动态生成对象
Console.WriteLine("二、用构造函数动态生成对象:");
Type t2 = typeof(NewClass);
//参数数组
Type[] pt2 = new Type[2];
pt2[0] = typeof(string);
pt2[1] = typeof(int);
//根据参数类型获取构造函数,有可能有多个构造函数
ConstructorInfo ci2 = t2.GetConstructor(pt2);
object[] obj2 = new object[2] { "s", 1 };
//调用构造函数,传递参数为obj
object o2 = ci2.Invoke(obj2);
//测试调用结果是否成功
((NewClass)o2).Show();
Console.WriteLine("----------------------------------------------------");
#endregion
#region 用Activator生成对象
Console.WriteLine("三、用Activator生成对象:");
Type t3 = typeof(NewClass);
//构造函数的参数
object[] obj3 = new object[2] { "hello", 11 };
//用Activator的CreateInstance静态方法,生成新对象
object o13 = Activator.CreateInstance(t3, "sun", 44);
object o23 = Activator.CreateInstance(t3, obj3);
object o33 = Activator.CreateInstance(t3);
///Activator.CreateInstance第一个参数为需要创建对象的类型,后面的为调用构造函数的参数,上面的三种格式都可以,只是调用的构造函数不同而已
((NewClass)o13).Show();
Console.WriteLine("----------------------------------------------------");
#endregion
#region 查看类中的属性
Console.WriteLine("四、查看类中的属性:");
NewClass nc4 = new NewClass();
Type t4 = nc4.GetType();
PropertyInfo[] pis4 = t4.GetProperties();
foreach (var pi in pis4)
{
Console.WriteLine(pi.Name);
}
Console.WriteLine("----------------------------------------------------");
#endregion
#region 查看类中的public方法
Console.WriteLine("五、查看类中的public方法:");
NewClass nc5 = new NewClass();
Type t5 = nc5.GetType();
MethodInfo[] mis5 = t5.GetMethods();
foreach (var mi in mis5)
{
Console.WriteLine(mi.ReturnType + " " + mi.Name);
}
Console.WriteLine("----------------------------------------------------");
#endregion
#region 查看类中的public字段
Console.WriteLine("六、查看类中的public字段:");
NewClass nc6 = new NewClass();
Type t6 = nc6.GetType();
FieldInfo[] fis6 = t6.GetFields();
foreach (var fi in fis6)
{
Console.WriteLine(fi.Name);
}
Console.WriteLine("----------------------------------------------------");
#endregion
#region 用反射生成对象,并调用属性、方法、字段进行操作
Console.WriteLine("七、用反射生成对象,并调用属性、方法、字段进行操作");
NewClass nc7 = new NewClass();
Type t7 = nc7.GetType();
object obj7 = Activator.CreateInstance(t7);
//取得ID字段
FieldInfo fi7 = t7.GetField("a");
//给ID字段赋值
fi7.SetValue(obj7, "sun");
//取得Name属性
PropertyInfo pi71 = t7.GetProperty("Name");
//给Name属性赋值
pi71.SetValue(obj7, "sun", null);
//取得Age属性
PropertyInfo pi72 = t7.GetProperty("Age");
//给Age属性赋值
pi72.SetValue(obj7, 200, null);
//取得show方法
MethodInfo mi7 = t7.GetMethod("Show");
//调用show方法
mi7.Invoke(obj7, null);
Console.WriteLine("----------------------------------------------------");
#endregion
Console.ReadKey();
}
}
System.Reflection.Assembly
Assembly类可以获得程序集的信息,也可以动态的加载程序集,以及在程序集中查找类型信息,并创建该类型的实例。
通过程序集名称返回Assembly对象
Assembly ass = Assembly.Load("ClassLibrary831");
通过DLL文件名称返回Assembly对象
Assembly ass = Assembly.LoadFrom("ClassLibrary831.dll");
通过Assembly获取程序集中类
Type t = ass.GetType("ClassLibrary831.NewClass");
//参数必须是类的全名
通过Assembly获取程序集中所有的类
Type[] t = ass.GetTypes();
如果要反射一个DLL中的类,并且是未知的类型,则可以这样操作:
Assembly assembly=Assembly.LoadFile("程序集路径,不能是相对路径");//加载程序集(exe或dll)
Object obj=assembly.CreateInstance("类的完全限定名(包括命名空间)");//创建类的实例