Type类使用来执行反射的主要类型之一
Type在反射中有什么的操作方法
如下为部分使用方式
class Program
{
static void Main(string[] args)
{
//反射只能操作程序集(C#)或者包(java),这是因为他们编译之后是IL中间语言,所以能通过反射获取到对应的信息
//但是C++编写的程序在编译之后就已经是机器码,所以C++的dll是不能使用反射来进行操作的
#region Type类能做什么
////获取一个对象的type的方式有两种
////1.直接创建一个对象,根据对象获取
//MyClass m = new MyClass();
//Type yp1 = m.GetType();
////直接获取,不需要创建类的对象
//Type tp2 = typeof(MyClass);
////1.获取父类的信息
//Console.WriteLine(tp2.BaseType.ToString());//父类
////Console.WriteLine(tp2.BaseType.BaseType.ToString());//父类的父类
////2.获取该类中所有的字段信息
////这里只能获取非私有的字段
//FieldInfo[] fields = tp2.GetFields();
//for (int i = 0; i < fields.Length; i++)
//{
// Console.WriteLine(fields[i].Name);
//}
////3.获取所有的属性信息
//PropertyInfo[] prpys = tp2.GetProperties();
//for (int i = 0; i < prpys.Length; i++)
//{
// Console.WriteLine(prpys[i].Name);
//}
////4.获取所有成员
//MemberInfo[] mis = tp2.GetMembers();
//for (int i = 0; i < mis.Length; i++)
//{
// Console.WriteLine(mis[i].Name);
//}
////5.获取所有方法
//MethodInfo[] mtis = tp2.GetMethods();
//for (int i = 0; i < mtis.Length; i++)
//{
// Console.WriteLine(mtis[i].Name);
//}
//6.获取私有成员
Type typesy = typeof(MyClass);
//这个只能调用共有的方法,调用私有的成员会报错
//应为这里SayHi是私有的,会找不到
//MethodInfo methodsy = typesy.GetMethod("SayHi");
//使用他的重载
MethodInfo methodsy = typesy.GetMethod("SayHi", BindingFlags.NonPublic | BindingFlags.Instance);
methodsy.Invoke(Activator.CreateInstance(typesy), null);
//Console.ReadKey();
#endregion Type类能做什么
//动态加载程序集并且调用
//1.根据dll文件的路径,动态加载程序集
Assembly asm = Assembly.LoadFile(@"C:\Users\Administrator\Desktop\test\NET基础加强\反射\TestDLL\bin\Debug\TestDLL.dll");
//2.根据动态加载的程序集,获取程序集中的类型
#region 获取程序集中的类型
//2.1获取所有类型
Type[] types = asm.GetTypes();
//输出一下
for (int i = 0; i < types.Length; i++)
{
Console.WriteLine("{0}\\{1}", types[i].FullName, types[i].Name);
}
Console.WriteLine("---------------------------------------------------------");
//2.2获取所有的Public类型
Type[] types2 = asm.GetExportedTypes();
//输出一下
for (int i = 0; i < types2.Length; i++)
{
Console.WriteLine("{0}\\{1}", types2[i].FullName, types2[i].Name);
}
Console.WriteLine("---------------------------------------------------------");
//2.3获取指定的类型,获取Persong类型
Type typePerson = asm.GetType("TestDLL.Person");
Console.WriteLine(typePerson.FullName);
Console.WriteLine("---------------------------------------------------------");
////获取参数的类型
//Type mm = typePerson.GetMethod("SayHello").GetParameters()[0].ParameterType;
#endregion 获取程序集中的类型
//3.调用获取到类型的方法
#region 调用获取到类型的方法
//获取指定的类型Person
Type perType = asm.GetType("TestDLL.Person");
//根据已经获取的类型获取指定的方法
MethodInfo meth = perType.GetMethod("SayHello");
//根据指定的type(类型),创建Person的对象
object obj = Activator.CreateInstance(perType);
//调用指定的方法
meth.Invoke(obj, null);
Console.WriteLine("---------------------------------------------------------");
//多个重载方法的调用,调用重载就是通过后面的Type数组来区分
//调用无参的重载方法,如果是多个重载,后面一个参数不能省略,否则会出现匹配不明确错误
MethodInfo mtehwc = perType.GetMethod("SayHi", new Type[] { });
mtehwc.Invoke(Activator.CreateInstance(perType), null);
Console.WriteLine("---------------------------------------------------------");
//调用有参的重载方法
MethodInfo mtehyc = perType.GetMethod("SayHi", new Type[] { typeof(string), typeof(string) });
mtehyc.Invoke(Activator.CreateInstance(perType), new object[] { "新增", "测试" });
Console.WriteLine("---------------------------------------------------------");
//调用有返回值得方法,Invoke是有返回值得,直接接收到的就是有返回值的方法的返回值
MethodInfo mtehfh = perType.GetMethod("Add", new Type[] { typeof(int), typeof(int) });
int r = (int)mtehfh.Invoke(Activator.CreateInstance(perType), new object[] { 10, 20 });
Console.WriteLine(r);
Console.WriteLine("---------------------------------------------------------");
#endregion 调用获取到类型的方法
//通过Type创建一个对象
#region 通过Type创建一个Person对象
Type personType = asm.GetType("TestDLL.Person");
//创建一个Person对象
//这里只能调用无参的构造函数,如果是有参的构造函数,则无法指定
object person1 = Activator.CreateInstance(personType);
//如果想要指定有参数的构造函数,则可以使用下面的方式
//通过调用指定的构造函数来创建Person对象
ConstructorInfo cuInfo = personType.GetConstructor(new Type[] { typeof(string), typeof(int) });
//调用构造函数来创建对象
object person2 = cuInfo.Invoke(new object[] { "盈盈", 18 });
//通过反射确定调用之后的值是否正确
PropertyInfo prperInfo = personType.GetProperty("Name");
//传入构造函数创建的对象,第二个参数索引器不需要,所以传null
string name = prperInfo.GetValue(person2, null).ToString();
Console.WriteLine(name);
Console.WriteLine("---------------------------------------------------------");
#endregion 通过Type创建一个Person对象
#region Type类操作
//使用IsAssignableFrom来判断是否可以把对象赋值给另一个对象
Type persoType = typeof(Person);
Type teatherType = typeof(Teather);
Type studentType = typeof(Student);
//表示检查能否将teatherType的对象赋值给persoType的对象
bool b = persoType.IsAssignableFrom(teatherType);//自身可以赋值
Console.WriteLine(b);
bool b1 = persoType.IsAssignableFrom(teatherType);//父子类关系也可以赋值
Console.WriteLine(b1);
bool b2 = persoType.IsAssignableFrom(studentType);
Console.WriteLine(b2);
bool b3 = teatherType.IsAssignableFrom(studentType);
Console.WriteLine(b3);
Console.WriteLine("---------------------------------------------------------");
//使用IsInstanceOfType检查某个对象是否是某个类型
object objPersong = Activator.CreateInstance(persoType);
object objTeacher = Activator.CreateInstance(teatherType);
object objStudent = Activator.CreateInstance(studentType);
Console.WriteLine(persoType.IsInstanceOfType(objPersong));
Console.WriteLine(persoType.IsInstanceOfType(objTeacher));//如果是父子关系也可以进行赋值
Console.WriteLine(persoType.IsInstanceOfType(objStudent));//如果是父子关系也可以进行赋值
Console.WriteLine(studentType.IsInstanceOfType(teatherType));
Console.WriteLine("---------------------------------------------------------");
//IsSubclassOf判断是否是父子类关系
//这里只能验证父子类关系,和接口的实现没有关系
Console.WriteLine(studentType.IsSubclassOf(persoType));
Console.WriteLine(teatherType.IsSubclassOf(persoType));
Console.WriteLine(persoType.IsSubclassOf(persoType));
Console.WriteLine(studentType.IsSubclassOf(teatherType));
Console.WriteLine("---------------------------------------------------------");
//验证是否是抽象的,不能被实例化的
//只要不能被实例化都会被认为是抽象的,包括接口,抽象类,静态类
Type ifly = typeof(IFlyable);
Console.WriteLine(persoType.IsAbstract);
Console.WriteLine(studentType.IsAbstract);
Console.WriteLine(teatherType.IsAbstract);
Console.WriteLine(ifly.IsAbstract);
Console.WriteLine("---------------------------------------------------------");
#endregion Type类操作
Console.ReadKey();
}
}
/// <summary>
/// 创建一个类
/// </summary>
public class MyClass
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public void Say()
{
Console.WriteLine("嗨");
}
private void SayHi()
{
Console.WriteLine("这是个私有的成员");
}
}
public class Person
{
}
public class Teather : Person
{
}
public class Student : Person
{
}
public interface IFlyable
{
}