标签:
1.前言
以前也写过几篇关于反射的博客(简单反射机制),但都理解的不是很深刻,现在在做项目中又一次的用到了反射,在此再总结一下,对于反射的理解。
2.什么是反射?
最近看博客,才理解了反射无处不在,我们经常用到的VS中的智能提示,就是通过反射获取到类的属性,方法等。反射就是动态获取程序集中的元数据来操作类型的。说的通俗一点,反射就是直接调用Bin文件夹下的.dll来创建对象,调用成员,摆脱了以前通过实例化也就是New操作的方法来调用对象的方法。
小结:反射就是直接调用.dll来创建对象,反射让创建对象的方式发生了变化。
3.什么是程序集(Assembly)
程序集是.net中的概念,比如.net中的.exe或者.dll文件都是程序集。可以把其看做是一堆相关的类的打包。比如包含一些资源文件、类型元数据等
其中调用Assembly(程序集)的GetTypes()方法可以得到程序集中定义的所有的类型
调用Assembly的GetType(name)方法可以得到Assembly中定义的全名为name的类型信息
3.Type类介绍
Type类是实现反射的一个重要的类,通过它可以获取类中所有的信息包括方法、属性等,通过它可以设置属性或者调用方法。
4.重要的类
Assembly:表示一个程序集,它是一个可重用、可自我描述的公共语言运行时应用程序构造块。
Type:表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。
MethodInfo:发现方法的属性并提供对方法元数据的访问。
PropertyInfo:发现属性 (Property) 的属性 (Attribute) 并提供对属性 (Property) 元数据的访问。
看了上图,就明白了反射其实就是另外一种机制,另外一种直接通过.dll文件来动态的创建类的对象。
5.Demo
以下是关于这方面知识,自己联系的Demo
<span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ClassLibrary1.dll");
//动态加载一个程序集
//C:\Users\ZHOU\Desktop\lianxi\ConsoleApplication2\bin\Debug
Assembly ass = Assembly.LoadFile("C:/Users/ZHOU/Desktop/lianxi/ConsoleApplication2/bin/Debug/ClassLibrary1.dll");
//获取程序集中公共的类型,通常指的是public的类
Type[] types = ass.GetExportedTypes();
foreach (Type type in types)
{
//类的名字
Console.WriteLine(type.Name);
//类的全名称(命名空间.类名)
Console.WriteLine(type.FullName);
}
//可以获取到所有的类,包括的是私有的类
//Type[] typ= ass.GetTypes();
foreach (Type item in types)
{
Console.WriteLine(item.Name);
}
Console.Read();
//使用FileCommon的默认构造函数创建对象
object o = ass.CreateInstance("commom.FileCommon");
Type t = o.GetType();
//使用指定参数的构造函数创建对象
object oo = Activator.CreateInstance(t, "zs", 18);
//判断student类型的对象,是否可以赋给person。类型的引用调换
bool r = typeof(Person).IsAssignableFrom(typeof(Student));
//判断学生对象是不是某个类的实例
Student b=new Student();
Type d=typeof(Student);
bool f=d.IsInstanceOfType(b);
//判断是不是某个类的子类
bool z = typeof(Person).IsSubclassOf(typeof(Student));
#region 动态获取程序集中的属性
//GetProperties获取类型中的所有属性
PropertyInfo[] pis = d.GetProperties();
foreach (PropertyInfo pi in pis)
{
if (pi.Name == "Name")
{
//动态给属性赋值
pi.SetValue(b, "jk", null);
pi.GetValue(b);
}
}
#endregion
//Type :描述类型的
//methodInfo:描述方法
#region 动态获取方法
MethodInfo[] mis = d.GetMethods();
foreach (MethodInfo mi in mis)
{
//获取子类中的扩展方法
if (mi.IsSpecialName)
{
}
}
#endregion
//动态调用Student类的SayHi方法
MethodInfo mid = d.GetMethod("Add");
mid.Invoke(d, null);
//也可以通过获取的type类型直接调用
b.Add();
}
}
interface Person
{
int Add();
};
class Student : Person
{
public int Add()
{
throw new NotImplementedException();
}
}
}
</span>
总结:反射其实就是另外一种创建对象的机制,只不过更灵活而已,关于以上提到的几个类,MSDN上有详细的解释,里面有很多可以用到的方法,想学习的可以查一下。
标签:
原文地址:http://blog.csdn.net/luckyzhoustar/article/details/42583677