您的位置:首页 > 编程语言 > C#

C#_Assembly-Reflection_程序集与反射

2015-12-01 08:13 543 查看
//Assembly:

  1..net的概念 .exe .dll (供加载用 本身不能执行 无入口函数主函数)

  2.包含

    类型元数据 (代码中定义的类型)

    程序集元数据 (描述程序集自身)

    IL代码

    资源文件

 ->使用程序集的好处:一是减小程序本身大小(因为可以只调用需要用到的dll)分模块 二是封装代码 向外提供接口

 ->如何添加程序集的引用:添加路径、项目引用、GAC(全局程序集缓存)          //不能循环添加引用 //C#中可调用其他程序所写的dll文件

//---------------------------------reflection--------------------------------------------------------------------

反射:可以理解为一种技术手段 拿到类型元数据

直接通过.dll来创建对象,调用成员  

我们先在同一个项目里创建主程序,然后新建另外一个程序集(在同一个项目下)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TestClassLibary
{
public class Class1
{

}

internal class PrivateMyClass
{

}

public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Email { get; set; }

}

public delegate void MyDelegate();

public interface IFlyable
{
void Fly();
}

}


类库
然后右键生成,找到Debug目录下的dll文件路径:

F:\Cheng_20140819\VS2012_WorkSpace\_Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibrary.dll

这样在我们主程序中就可以动态加载啦.. ^_~

酱紫:

#region 获取另外一个程序集中的类型
//动态加载程序集
Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");

//这里的GetType()   等价于 TypeOf(Assembly)  不能获取所有程序集中所有类型

//利用GetTypes获取所有类型          public  internal  都能拿到
Type[] ts = ass.GetTypes();
foreach (Type item in ts)
{
Console.WriteLine(  item.Name);
}

//只获取公开的类型
//获取导出的类型
Type[] publicTypes = ass.GetExportedTypes();
foreach (Type item in publicTypes)
{
Console.WriteLine("--->>"+item.Name);
}
#endregion


当然我们若是要获取指定的类型 调用重载:

Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\20151129_Heima_Day11_Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");

//---------------------------------------------这里假设在获取到的Person类中 有Add方法 一个返回值 两个参数     添加方法之后要记得重新生成

//获取特定的Type
Type personType = ass.GetType("TestClassLibary.Person"); //类型需要完全限定名称 : 记得带上命名空间哟~

//根据特定的Type 来创建对象
object personObj = Activator.CreateInstance(personType);

//获取特定的方法
MethodInfo method = personType.GetMethod("Add");

//调用
object obj= method.Invoke(personObj, new object[] { 2, 3 });    //参数1 代表获取的类型的对象 ,参数2 代表调用的方法的参数列表

//--------------------------------调用属性---------------------

Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");

Type t = ass.GetType("TestClassLibary.Person");

object obj = Activator.CreateInstance(t);

PropertyInfo pifo = t.GetProperty("Name");

pifo.SetValue(obj, "cheng");

MethodInfo mifo = t.GetMethod("WriteName");

mifo.Invoke(obj, null);


//--------------------------------利用特定的构造函数

#region 手动查找构造函数 并且调用该构造函数来创建类型的对象
Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\20151129_Heima_Day11_Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");

Type personType=ass.GetType("TestClassLibary.Person");

        //这里使用 ctor    GetConstructor()  其参数列表就 是指定的构造函数的列表
ConstructorInfo ctor= personType.GetConstructor(new Type[] { typeof(string),typeof(int),typeof(string)});
object o =  ctor.Invoke(new object[] {"ccc",20,"CCC@sina.cn" });
Console.WriteLine(o.ToString());
MethodInfo mInfo = personType.GetMethod("WriteName");
mInfo.Invoke(o, null);

#endregion


12月02日 补充:

拿到某个类型PType之后 要拿到私有方法的话 需要调用 :MethodInfo privateMethodName= PType.GetMethod("SayHi",BindingFlags.NonPublic|BindingFlags.Instance);

就可以拿到某个类型的私有方法了 ^_~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: