c#加载程序集调用的方法说明

程序集加载

程序集加载,CLR使用System.Reflection.Assembly.Load静态方法,当然这个方法我们自己也可以显式调用。

还有一个Assembly.LoadFrom方法加载指定路径名的程序集,实际上其内部是先通过AssemblyName.GetAssemblyName获取AssemblyName对象,然后调用Assembly.Load方法。

此时load方法会在各个位置(前面03章讲过)查找程序集,如果已经加载了此程序集就返回已加载的程序集,如果没有加载就去加载找到的程序集,如果没有找到,就加载路径所给的那个程序集。(所以很清楚了解到不一定会加载所指定的那个程序集,而可能是另一个。在这里如果每次生成强命名程序集时更新版本号,才会使LoadFrom方法的行为符合预期)

LoadFrom方法允许传递一个Url作为实参,CLR会下载文件,把它安装到用户的下载缓存中,再从那儿加载文件。

ReflectionOnlyLoadFrom函数也可以加载程序集,且禁止程序集中的任何代码执行。

使用反射构建动态可扩展应用程序

既然加载了程序集,那么就应该要有办法去使用程序集中定义的类,这种办法就是反射。

利用System.Reflection命名空间中包含的类型,可以写代码来反射元数据表,为所加载的程序集中所包含的元数据提供对象模型。

反射一些例子:

首先先建立一个用于反射的程序集,代码如下:

复制代码

namespace HelloWorld

{

   public class Man

   {

       public string _name;

       public Man(String name) {

           this._name = name;

       }

       public void ShowName() {

           Console.WriteLine(this._name);

       }

   }

}

namespace HelloWorld

{

   public class Troy:Man

   {

       private string _jobName;

public Troy(string name,string jobName):base(name) {

this._jobName = jobName;

}

public void ShowJobName() {

Console.WriteLine(this._jobName);

}

}

}

复制代码

然后生成了一个叫HelloWorld.dll的文件,然后开始玩反射

复制代码

      //首先加载程序集,获取程序集对象

Assembly myAssembly=Assembly.LoadFrom("D:\\HelloWorld.dll");

//玩程序集中定义的公共类型

foreach (Type type in myAssembly.ExportedTypes) {

//打印类型全名

Console.WriteLine("类型全名:"+type.FullName);

Console.WriteLine(type.FullName + "的基类:" + type.BaseType.FullName);

//判定类型是否为String(当然这是不可能的,因为只有Man和Troy)

if (type == typeof(String)) {

Console.WriteLine("有个String类型");

}

//Type对象是轻量型的类型引用,更全面的信息在TypeInfo对象(获取TypeInfo对象会强迫CLR确保已加载类型的定义程序集,从而对类型进行解析。(代价高昂)),

//如下转换

TypeInfo typeInfo = IntrospectionExtensions.GetTypeInfo(type);

//也可以反着转

Type tmpType = typeInfo.AsType();

//泛型类型的Type

Type openType = typeof(Dictionary<,>);//开放类型

Type closedType= openType.MakeGenericType(typeof(int), type);//闭合类型

//实例化

Object obj= Activator.CreateInstance(closedType);

Console.WriteLine(obj.GetType());

}

复制代码

反射的性能

反射是相当强大的机制,但是也有其缺点:

反射造成编译时无法保证类型安全性,因为它是在运行时才依靠字符串来对类进行实例化等操作。

反射的速度很慢,因为是在运行时靠字符串去标识成员,发现它们,使用它们。整个过程中都是用字符串来搜索。

设计支持加载项的应用程序

构建可扩展应用程序时,一般使用接口而不是基类,因为接口允许加载项开发人员选择自己的基类。

为宿主接口类的方法定义参数和返回类时,尝试使用MSCorLib.dll定义的接口和类型。因为CLR只加载一个MSCorLib.dl,所以不会出现类型版本不匹配的情况,且有助于减少应用程序对内存的需求。

反射与类型的成员

System.Reflection.MemberInfo封装了所有类型成员都通用的一组属性。它的一些派生类如MethodInfo则封装了与特定类型成员相关的更多属性。

直接上代码简单易懂:

复制代码

class Program

   {

       static void Main(string[] args)

       {

           Type type = typeof(Troy);

           Object obj = Activator.CreateInstance(type);

           MethodInfo[] arrMethod= type.GetMethods();

           foreach (var methodInfo in arrMethod) {

               if (methodInfo.GetParameters().Length == 0)

               {

                   methodInfo.Invoke(obj, null);

               }

           }

           Console.Read();

       }

   }

   public class Troy{

       public string name;

       public Troy() {

           name = "Troy";

       }

       public void Show() {

           Console.WriteLine(name);

       }

   }

复制代码

对于FieldInfo(字段)和PropertyInfo(属性)可以用GetValue和SetValue来获取和设置实例的值,

对于MethodInfo(方法)和ConstructorInfo(构造器)则可以用Invoke来调用,

对于EventInfo(事件)可以用AddEventHandler和RemoveHandler来增加事件回调函数和减少回调函数。

上述方法其实很麻烦,如果用dynamic方法那么就会和一般的写程序一样简单了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,961评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,444评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,009评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,082评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,101评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,271评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,738评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,395评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,539评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,434评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,481评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,160评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,749评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,816评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,038评论 1 256
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,548评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,140评论 2 341

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,569评论 18 139
  • 1. [C#语言基础]请简述拆箱和装箱。 答: 装箱操作: 值类型隐式转换为object类型或由此值类型实现的任何...
    胤醚貔貅阅读 4,757评论 1 29
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,538评论 18 399
  • 杨青龙_c416阅读 203评论 0 0
  • 昨晚下班时候天还没有黑下来,我就想到要去开始跑步了。毕竟2017年年初,我也郑重写过我的梦想清单,不行动,真的找不...
    韩小姐的城堡阅读 197评论 0 0