《CLR Via C#(第三版)》 第二十三章

本文详细解析了.NET Framework中的程序集加载机制及反射技术的使用,包括程序集的加载过程、性能考量、类型对象的含义、实例创建方法、类型成员的发现与调用等关键概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第23章 程序集加载和反射

23.1 程序集加载

CLR使用System.Reflection.Assembly类的静态方法Load来尝试加载程序集。

Load导致CLR向程序集应用一个版本绑定重定向策略,并在GAC(全局程序集缓存)中查找程序集。如果没找到,就接着去应用程序的基目录、私有路径子目录和codebase位置查找。

<?xml version="1.0" encoding="utf-8" ?>
<!--App.config-->
<configuration>
  <runtime>
    <assemblyBinding>
      <assemblyIdentity name="***" />
      <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
      <codeBase version="2.0.0.0" href="http://www.wintellect.com"/>
    </assemblyBinding>
  </runtime>
</configuration>

23.3 反射的性能

反射会造成编译时无法保证类型安全性。由于反射要严重依赖字符串,所以会丧失编译时的类型安全性。

反射速度慢。

23.3.2 类型对象的准确含义

System.Type类型是执行类型和对象的起点。System.Type是一个从System.Reflection.MemberInfo派生的抽象基类。

23.3.4 构造类型的实例

1). System.Activator的CreateInstance方法

2). System.Activator的CreateInstanceFrom方法

3). System.AppDomain的方法

4). System.Type的InvokeMember实例方法

5). System.Reflection.ConstructorInfo的Invoke实例方法

创建数组类型实例应该调用Array的静态CreateInstance方法。

创建委托实例,应该调用Delegate的静态CreateDelegate方法。

创建泛型类型实例,应该首先要获取对开放类型的一个引用,然后调用Type的公共实例方法MakeGenericType。

        Type genericType = typeof(Dictionary<,>);
        Type genericType2 = genericType.MakeGenericType(typeof(int), typeof(List<int>));
        object instance = Activator.CreateInstance(genericType2);
        Console.WriteLine(instance);

23.5 使用反射发现类型的成员

23.5.1 发现类型成员

FCL包含一个名为System.Reflection.MemberInfo的类型。这是一个抽象类型,封装了一组所有类型成员都通用的属性。从MemberInfo派生的一组类,每个类都封装了与一个特定类型成员相关的更多属性。


        Type genericType = typeof(Class1);

        foreach (var f in genericType.GetFields())
            Console.WriteLine(f.Name);

        foreach (var m in genericType.GetMethods())
            Console.WriteLine(m.Name);

        foreach (var c in genericType.GetConstructors())
            Console.WriteLine(c.Name);

        foreach (var p in genericType.GetProperties())
            Console.WriteLine(p.Name);

        foreach (var e in genericType.GetEvents())
            Console.WriteLine(e.Name);

23.5.2 BindingFlags:筛选返回的成员种类

可以调用Type的GetMembers,GetNestedTypes,GetFields,GetConstructors,GetMethods,GetProperties或者GetEvents方法来查询一个类型的成员。调用上述任何一个方法时,可以传递System.Reflection.BindingFlags枚举类型的一个实例。这个枚举类型标识了一组通过逻辑OR运算合并到一起的标志(bit flag),目的是对这些方法返回的成员进行筛选。

        Type genericType = typeof(Class1);

        foreach (var m in genericType.GetMethods(BindingFlags.Instance|BindingFlags.Public|BindingFlags.Static))
            Console.WriteLine(m.Name);

23.5.4 调用类型的成员

调用一个FieldInfo,可以获取或设置字段的值:调用一个ConstructorInfo,可以向构造器传递实参,从而构造类型的一个实例;调用一个MethodInfo,可以通过传递实例来调用方法,并获得它的返回值;调用PropertyInfo,可以调用(call)属性的get和set访问器方法;而调用一个EventInfo可以添加或删除一个事件处理程序。

Type类提供了一个InvokeMember访问,可通过它调用一个成员。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值