反射
目的:能够动态的调用方法,对属性赋值
Assemby类是对程序集的描述
• 所有.Net类都是定义在某个Assembly(程序集)中的,.Net基本类是定义在mscorlib.dll中。exe也可以看做是类库,也可以引用。.net的exe也是Assembly,.net中的exe和dll的区别就是exe中包含入口函数,其他没有区别,exe也可以当成dll那样引用、也可以反编译。
• GAC:全局程序集缓存。公用的Assembly放到GAC中。(*)
• Assembly类是对Assembly的描述(*)。
– AppDomain.CurrentDomain.GetAssemblies()获得程序所有的Assembly
– Assembly.LoadFile(),动态从文件加载Assembly,不需要在编译的时候引用。
反射:Type类(*)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using SayHelloable;
namespace 反射
{
class Program
{
static void Main(string[] args)
{
Assemblyasm = Assembly.LoadFile(@"D:\传智播客\练习\反射\实现\bin\Debug\实现.exe");
//Type[]ty = asm.GetTypes();
//foreach(Type item in ty)
//{
// Console.WriteLine(item.ToString());
//}
Typety = asm.GetTypes()[1];
//activator.CreateInstance用于创建类的类实例
objectobj = Activator.CreateInstance(ty);
ISayHelloablesay = obj as ISayHelloable;
say.SayHello();
Console.ReadKey();
}
}
}
• 参考教材:《C#高级编程》7.5、7.6
• Type类可以叫做“类的类”,一个类型对应一个Type类的对象,通过Type对象可以获得类的所有的定义信息,比如类有哪些属性、哪些方法等。Type就是对类的描述。
• 获得Type对象的方法:
– 通过类获得Type:Type t = typeof(Person)
– 通过对象获得类的Type:Type t = p.GetType()
– 调用Assembly的GetExportedTypes方法可以得到Assembly中定义的所有的public类型。
– 调用Assembly的GetTypes()方法可以得到Assembly中定义的所有的类型。
– 调用Assembly的GetType(name)方法可以得到Assembly中定义的全名为name的类型信息。
• Activator.CreateInstance(Typet)会动态调用类的无参构造函数创建一个对象,返回值就是创建的对象,如果类没有无参构造函数就会报错。
• 应用:通过配置文件动态创建对象。
• Type类的方法:
– bool IsAssignableFrom(Type c):(直译:是否可以从c赋值)判断当前的类型的变量是不是可以接受c类型变量的赋值。ISettingsProvidersp; DbSettingsProvider bsp; AccessSettingsProvider msp; sp可以从bsp、msp赋值(sp=bsp;sp=msp)。 bsp可以从msp赋值(bsp=msp)。
– bool IsInstanceOfType(object o):判断对象o是否是当前类的实例(当前类可以是o的类、父类、接口)
– bool IsSubclassOf(Type c):判断当前类是否是类c的子类。类的事,没有接口的事。如果当前类是MemSettingsProvider,c是ISettingsProvider,则返回false。
反射可以调用私有方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using SayHelloable;
namespace 反射
{
class Program
{
static void Main(string[] args)
{
Personp=new Person();
TypetypePerson = typeof(Person);
PropertyInfoName= typePerson.GetProperty("Name");//用反射获取属性并且为其设值
Name.SetValue(p, "tom", null);
PropertyInfoAge = typePerson.GetProperty("Age");
Age.SetValue(p, 30, null);
MethodInfomethodinfo= typePerson.GetMethod("GetInfo");//用反射获取方法
//调用私有方法,利用反射的方法可以调用类的私有成员
MethodInfomethodinfo1 = typePerson.GetMethod("haha",BindingFlags.Instance|BindingFlags.NonPublic);
methodinfo1.Invoke(p,null);
Console.WriteLine( methodinfo.Invoke(p, null));
Console.ReadKey();
}
}
public class Person
{
public string Name
{
set;
get;
}
public int Age
{
set;
get;
}
public string GetInfo()
{
return"姓名:"+ Name +"年龄:"+ Age;
}
private void haha()
{
Console.WriteLine("哈哈");
}
}
}