65.9K
CodeProject 正在变化。 阅读更多。
Home

NET 中的反射

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (141投票s)

2010 年 2 月 9 日

CPOL

12分钟阅读

viewsIcon

502343

downloadIcon

5281

.NET Framework 的反射 API 允许您在运行时获取类型(程序集)信息。

目录

引言

在本文中,我试图涵盖 .NET 反射的所有主题,并附带示例。我从 .NET 反射的定义及其路线图开始,列出了 System.Reflection 命名空间提供的大部分常用类,以及 Type 类在 .NET 反射中的重要性。您还将学习如何通过不同方式获取类型信息。本文解释了如何在 .NET 反射中使用 Type 类的属性和方法,并附带示例。您还将在本文末尾看到高级反射主题,如动态加载程序集和后期绑定。

什么是 .NET 反射?

.NET Framework 的反射 API 允许您通过编程方式在运行时获取类型(程序集)信息。我们还可以使用 .NET 反射来实现后期绑定。在运行时,反射机制使用 PE 文件读取有关程序集的信息。反射使您能够使用在编译时不可用的代码。.NET 反射允许应用程序收集有关自身的信息,并对其自身进行操作。它可以有效地用于查找程序集中的所有类型和/或动态调用程序集中的方法。这包括有关类型、属性、方法和对象事件的信息。通过反射,我们可以动态创建类型的实例,将类型绑定到现有对象,或者从现有对象获取类型并调用其方法或访问其字段和属性。我们还可以使用反射访问属性信息。

使用反射,您可以获取在类查看器中可以看到的任何类型的信息;例如,有关对象的方法、属性、字段和事件的信息。

System.Reflection 命名空间和 System.Type 类在 .NET 反射中起着非常重要的作用。它们协同工作,允许您反射类型的许多其他方面。

路线图

System.Reflection 命名空间

System.Reflection 命名空间包含类和接口,它们提供已加载类型、方法和字段的托管视图,并能够动态创建和调用类型;此过程称为 .NET Framework 中的反射。我们将在此处介绍一些常用的类。

描述
程序集 表示程序集,它是公共语言运行时应用程序的可重用、可版本化且自描述的构建块。此类包含许多允许您加载、检查和操作程序集的方法。
模块 对模块执行反射。此类允许您访问多文件程序集中的给定模块。
AssemblyName 此类允许您发现程序集标识背后的许多详细信息。程序集的标识包括以下内容:
  • 简单名称
  • 版本号
  • 加密密钥对
  • 支持的区域性
EventInfo 此类保存给定事件的信息。使用 EventInfo 类检查事件并绑定到事件处理程序。
FieldInfo 此类保存给定字段的信息。字段是类中定义的变量。FieldInfo 提供对类中字段元数据的访问,并为该字段提供动态设置和获取功能。在调用对象的 Invokeget 之前,此类不会加载到内存中。
MemberInfo MemberInfo 类是用于获取有关类所有成员(构造函数、事件、字段、方法和属性)信息的类的抽象基类。
MethodInfo 此类包含给定方法的相关信息。
ParameterInfo 此类保存给定参数的信息。
PropertyInfo 此类保存给定属性的信息。

在开始使用反射之前,了解 System.Type 类是必要的。

为了继续阅读本文中的所有示例,我使用了一个 Car 类作为示例。它看起来像这样:

// ICar.cs - Interface 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Reflection 
{ 
    interface ICar 
    { 
        bool IsMoving(); 
    } 
}

// Car.cs - Class 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Reflection 
{ 
    internal class Car 
    { 
        //public variables 
        public string Color; 

        //private variables 
        //String licensePlate; // e.g. "Californi 111 222" 
        //double maxSpeed;     // in kilometers per hour 
        //int startMiles; // Stating odometer reading 
        //int endMiles; // Ending odometer reading 
        //double gallons; // Gallons of gas used between the readings  

        //private vaiables 
        private int _speed; 

        //Speed - read-only property to return the speed 
        public int Speed 
        { 
            get { return _speed; } 
        } 

        //Accelerate - add mph to the speed 
        public void Accelerate(int accelerateBy) 
        { 
            //Adjust the speed 
            _speed += accelerateBy; 
        } 

        //IsMoving - is the car moving? 
        public bool IsMoving() 
        { 
            //Is the car's speed zero? 
            if (Speed == 0) 
            { 
                return false; 
            } 
            else 
            { 
                return true; 
            } 
        } 

        //Constructor 
        public Car() 
        { 
            //Set the default values 
            Color = "White"; 
            _speed = 0; 
        } 

        //Over loaded constructor 
        public Car(string color, int speed) 
        { 
            Color = color; 
            _speed = speed; 
        } 

        //methods 
        public double calculateMPG(int startMiles, int endMiles, double gallons) 
        { 
            return (endMiles - startMiles) / gallons; 
        }  
    }
}

// SportsCar.cs - Class 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace Reflection 
{ 
    internal class SportsCar : Car 
    { 
        //Constructor 
        public SportsCar() 
        { 
            //Change the default values 
            Color = "Green"; 
        } 
    }
}

System.Type 类

System.Type 类是 .NET 反射功能的主要类,也是访问元数据的主要方式。System.Type 类是一个抽象类,代表 **Common Type System** (CLS) 中的一个类型。

它表示类型声明:类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义以及开放或封闭的构造泛型类型。

使用 Type 的成员来获取有关类型声明的信息,例如类的构造函数、方法、字段、属性和事件,以及类部署所在的模块和程序集。

有三种方法可以获取 Type 引用:

使用 System.Object.GetType()

此方法返回一个 Type 对象,该对象表示实例的类型。显然,如果您在编译时了解该类型,这种方法才有效。

// ObjectGetTypeDemo.cs 
using System; 
namespace Reflection 
{ 
    class ObjectGetTypeDemo 
    { 
        static void Main(string[] args) 
        { 
            Car c = new Car(); 
            Type t = c.GetType(); 
            Console.WriteLine(t.FullName); 
            Console.ReadLine(); 
        } 
    } 
}

输出

Reflection.Car

使用 System.Type.GetType()

另一种更灵活地获取类型信息的方法是 Type 类的静态方法 GetType(),它通过区分大小写的搜索来获取具有指定名称的类型。

Type.GetType() 是一个重载方法,它接受以下参数:

  1. 您有兴趣检查的类型的完全限定字符串名称
  2. 如果找不到该类型,应抛出的异常
  3. 建立字符串的区分大小写
// TypeGetTypeDemo.cs 
using System; 
namespace Reflection 
{ 
    class TypeGetTypeDemo 
    { 
        static void Main(string[] args) 
        { 
            // Obtain type information using the static Type.GetType() method. 
            // (don't throw an exception if Car cannot be found and ignore case). 
            Type t = Type.GetType("Reflection.Car", false, true); 

            Console.WriteLine(t.FullName); 
            Console.ReadLine(); 
        } 
    } 
}

输出

Reflection.Car

使用 typeof() C# 运算符

获取类型信息的最后一种方法是使用 C# typeof 运算符。此运算符以类型名称作为参数。

// TypeofDemo.cs 
using System; 
namespace Reflection 
{ 
    class TypeofDemo 
    { 
        static void Main(string[] args) 
        { 
            // Get the Type using typeof. 
            Type t = typeof(Car); 
            Console.WriteLine(t.FullName); 
            Console.ReadLine(); 
        } 
    } 
}

输出

Reflection.Car

类型属性

System.Type 类定义了许多可用于检查类型元成员的成员,其中许多成员返回来自 System.Reflection 命名空间的类型。

您可以将 Type 实现的属性分为三类:

  1. 许多属性检索包含与类相关的各种名称的字符串,如下表所示:
  2. 属性 Returns
    名称 数据类型的名称。
    FullName 数据类型的完全限定名称(包括命名空间名称)。
    命名空间 定义数据类型的命名空间的名称。
  3. 还可以检索表示相关类的其他类型对象的引用,如下表所示:
  4. 属性 返回类型引用对应于
    BaseType 此类型的直接基类型。
    UnderlyingSystemType 此类型映射到的 .NET 运行时类型(请记住,某些 .NET 基类型实际上映射到 IL 识别的特定预定义类型)。
  5. 许多布尔属性指示此类型是类、枚举等。
  6. 类型 生命意义
    • IsAbstract
    • IsArray
    • IsClass
    • IsCOMObject
    • IsEnum
    • IsGenericTypeDefinition
    • IsGenericParameter
    • IsInterface
    • IsPrimitive
    • IsPublic
    • IsNestedPrivate
    • IsNestedPublic
    • IsSealed
    • IsValueType
    • IsPointer
    这些属性(以及其他属性)允许您发现有关您引用的类型的许多基本特征。

以下是使用 System.Type 类属性显示类型信息的示例:

// TypePropertiesDemo.cs 
using System; 
using System.Text; 
using System.Reflection; 

namespace Reflection 
{ 
    class TypePropertiesDemo 
    { 
        static void Main() 
        { 
            // modify this line to retrieve details of any other data type 
            // Get name of type 
            Type t = typeof(Car); 
            GetTypeProperties(t); 
            Console.ReadLine(); 
        } 
        public static void GetTypeProperties(Type t) 
        { 
            StringBuilder OutputText = new StringBuilder(); 

            //properties retrieve the strings 
            OutputText.AppendLine("Analysis of type " + t.Name); 
            OutputText.AppendLine("Type Name: " + t.Name); 
            OutputText.AppendLine("Full Name: " + t.FullName); 
            OutputText.AppendLine("Namespace: " + t.Namespace); 

            //properties retrieve references        
            Type tBase = t.BaseType; 

            if (tBase != null) 
            { 
                OutputText.AppendLine("Base Type: " + tBase.Name); 
            } 

            Type tUnderlyingSystem = t.UnderlyingSystemType; 

            if (tUnderlyingSystem != null) 
            { 
                OutputText.AppendLine("UnderlyingSystem Type: " +
                    tUnderlyingSystem.Name); 
                //OutputText.AppendLine("UnderlyingSystem Type Assembly: " +
                //    tUnderlyingSystem.Assembly); 
            } 

            //properties retrieve boolean         
            OutputText.AppendLine("Is Abstract Class: " + t.IsAbstract); 
            OutputText.AppendLine("Is an Arry: " + t.IsArray); 
            OutputText.AppendLine("Is a Class: " + t.IsClass); 
            OutputText.AppendLine("Is a COM Object : " + t.IsCOMObject); 

            OutputText.AppendLine("\nPUBLIC MEMBERS:"); 
            MemberInfo[] Members = t.GetMembers(); 

            foreach (MemberInfo NextMember in Members) 
            { 
                OutputText.AppendLine(NextMember.DeclaringType + " " + 
                NextMember.MemberType + "  " + NextMember.Name); 
            } 
            Console.WriteLine(OutputText); 
        } 
    } 
}

输出

Analysis of type Car 
Type Name: Car 
Full Name: Reflection.Car 
Namespace: Reflection 
Base Type: Object 
UnderlyingSystem Type: Car 
Is Abstract Class: False 
Is an Arry: False 
Is a Class: True 
Is a COM Object : False

公共成员

Reflection.Car Method  get_Speed 
Reflection.Car Method  Accelerate 
Reflection.Car Method  IsMoving 
Reflection.Car Method  calculateMPG 
System.Object Method  ToString 
System.Object Method  Equals 
System.Object Method  GetHashCode 
System.Object Method  GetType 
Reflection.Car Constructor  .ctor 
Reflection.Car Constructor  .ctor 
Reflection.Car Property  Speed 
Reflection.Car Field  Color

类型方法

System.Type 的大多数方法用于获取相应数据类型的成员的详细信息——构造函数、属性、方法、事件等。存在大量方法,但它们都遵循相同的模式。

返回类型 方法(复数名称的方法返回一个数组) 描述
ConstructorInfo GetConstructor(), GetConstructors() 这些方法允许您获取一个数组,该数组表示您感兴趣的项目(接口、方法、属性等)。每个方法返回一个相关的数组(例如,GetFields() 返回一个 FieldInfo 数组,GetMethods() 返回一个 MethodInfo 数组等)。请注意,这些方法中的每一种都有一个单数形式(例如,GetMethod(), GetProperty() 等),允许您通过名称检索特定项目,而不是所有相关项目的数组。
EventInfo GetEvent(), GetEvents()
FieldInfo GetField(), GetFields()
InterfaceInfo GetInterface(), GetInterfaces()
MemberInfo GetMember(), GetMembers()
MethodInfo GetMethod(), GetMethods()
PropertyInfo GetProperty(), GetProperties()
  FindMembers() 此方法根据搜索条件返回一个 MemberInfo 类型数组。
类型 GetType() 此静态方法在给定字符串名称的情况下返回一个 Type 实例。
  InvokeMember() 此方法允许对给定项进行后期绑定。

例如,有两个方法用于检索数据类型方法的详细信息:GetMethod() 和 GetMethods()。

Type t = typeof(Car); 
MethodInfo[] methods = t.GetMethods(); 
foreach (MethodInfo nextMethod in methods) 
{ 
                // etc. 
}

反射方法

GetMethod() 返回一个 System.Reflection.MethodInfo 对象的引用,该对象包含方法的详细信息。搜索具有指定名称的公共方法。

GetMethods() 返回此类引用的数组。区别在于 GetMethods() 返回所有方法的详细信息,而 GetMethod() 只返回具有指定参数列表的单个方法的详细信息。

这两个方法都有接受额外参数的重载,该参数是 BindingFlags 枚举值,指示应返回哪些成员——例如,是否返回公共成员、实例成员、静态成员等。

MethodInfo 派生自抽象类 MethodBase,后者继承 MemberInfo。因此,所有这三个类定义的属性和方法都可供您使用。

例如,GetMethods() 的最简单的重载不接受任何参数:

// GetMethodsDemo.cs 
using System; 
using System.Reflection; 

namespace Reflection 
{ 
    class GetMethodsDemo 
    { 
        static void Main() 
        { 
            // Get name of type 
            Type t = typeof(Car); 
            GetMethod(t); 
            GetMethods(t); 

            Console.ReadLine(); 
        } 

        // Display method names of type. 
        public static void GetMethods(Type t) 
        { 
            Console.WriteLine("***** Methods *****"); 
            MethodInfo[] mi = t.GetMethods(); 
            foreach (MethodInfo m in mi) 
                Console.WriteLine("->{0}", m.Name); 
            Console.WriteLine(""); 
        } 

        // Display method name of type. 
        public static void GetMethod(Type t) 
        { 
            Console.WriteLine("***** Method *****"); 
            //This searches for name is case-sensitive. 
            //The search includes public static and public instance methods. 
            MethodInfo mi = t.GetMethod("IsMoving"); 
            Console.WriteLine("->{0}", mi.Name); 
            Console.WriteLine(""); 
        } 
    } 
}

输出

***** Method ***** 
->IsMoving 
***** Methods ***** 

->get_Speed 
->Accelerate 
->IsMoving 
->calculateMPG 
->ToString 
->Equals 
->GetHashCode 
->GetType

在这里,您只是使用 MethodInfo.Name 属性打印方法的名称。正如您可能猜到的,MethodInfo 有许多额外的成员,允许您确定方法是 staticvirtual 还是 abstract。此外,MethodInfo 类型允许您获取方法的返回值和参数集。

GetMethods( ) 的第二种形式

GetMethods( ) 的第二种形式允许您指定各种筛选检索方法的标志。它具有以下通用形式:

MethodInfo[ ] GetMethods(BindingFlags flags)

此版本仅获取与您指定的条件匹配的方法。BindingFlags 是一个枚举。以下是一些常用的值:

含义
DeclaredOnly 仅检索指定类中定义的方法。不包括继承的方法。
实例 检索实例方法。
NonPublic 检索非公共方法。
Public 检索公共方法。
静态 检索静态方法。

您可以将两个或多个标志 OR 组合在一起。事实上,至少,您必须包含 InstanceStatic 以及 PublicNonPublic。否则将不会检索到任何方法。

GetMethods( )BindingFlags 形式的主要用途之一是允许您获取一个类定义的方法列表,而不检索继承的方法。这对于防止获取对象定义的方法特别有用。例如,尝试将此 GetMethods( ) 调用替换到前面的程序中:

// Now, only methods declared by MyClass are obtained. 

MethodInfo[] mi = t.GetMethods(BindingFlags.DeclaredOnly | 
                               BindingFlags.Instance |
                               BindingFlags.Public);

反射字段和属性

Type.GetField()Type.GetFields() 的行为与上述两个方法完全相似,只是 Type.GetField() 返回 System.Reflection.MethodInfo 的引用,而 Type.GetFields() 返回 System.Reflection.MethodInfo 数组的引用。同样,Type.GetProperty()Type.GetProperties() 也是如此。

显示类型属性的逻辑类似:

// GetFieldsPropertiesDemo.cs 
using System; 
using System.Reflection; 

namespace Reflection 
{ 
    class GetFieldsPropertiesDemo 
    { 
        static void Main() 
        { 
            // Get name of type 
            Type t = typeof(Car); 
            GetFields(t); 
            GetProperties(t); 

            Console.ReadLine(); 
        } 

        // Display field names of type. 
        public static void GetFields(Type t) 
        { 
            Console.WriteLine("***** Fields *****"); 
            FieldInfo[] fi = t.GetFields(); 
            foreach (FieldInfo field in fi) 
                Console.WriteLine("->{0}", field.Name); 
            Console.WriteLine(""); 
        } 

        // Display property names of type. 
        public static void GetProperties(Type t) 
        { 
            Console.WriteLine("***** Properties *****"); 
            PropertyInfo[] pi = t.GetProperties(); 
            foreach (PropertyInfo prop in pi) 
                Console.WriteLine("->{0}", prop.Name); 
            Console.WriteLine(""); 
        } 
    }
}

输出

***** Fields ***** 
->Color 
***** Properties ***** 
->Speed

反射已实现的接口

GetInterfaces() 返回一个 System.Type 数组!考虑到接口确实是类型,这应该是合乎逻辑的。

// GetInterfacesDemo.cs 
using System; 
using System.Reflection; 

namespace Reflection 
{ 
    class GetInterfacesDemo 
    { 
        static void Main() 
        { 
            // Get name of type 
            Type t = typeof(Car); 
            GetInterfaces(t); 

            Console.ReadLine(); 
        } 

        // Display implemented interfaces. 
        public static void GetInterfaces(Type t) 
        { 
            Console.WriteLine("***** Interfaces *****"); 
            Type[] ifaces = t.GetInterfaces(); 
            foreach (Type i in ifaces) 
                Console.WriteLine("->{0}", i.Name); 
        } 
    } 
}

输出

***** Interfaces ***** 
->ICar

反射方法参数和返回值

为了处理方法参数和返回值,我们首先需要使用 GetMethods() 函数构建一个 MethodInfo[] 数组。

MethodInfo 类型提供了 ReturnType 属性和 GetParameters() 方法来完成这些任务。

using System; 
using System.Reflection; 
using System.Text; 

namespace Reflection 
{ 
    class GetParameterInfoDemo 
    { 
        static void Main() 
        { 
            // Get name of type 
            Type t = typeof(Car); 
            GetParametersInfo(t); 

            Console.ReadLine(); 
        } 

        //Display Method return Type and paralmeters list 
        public static void GetParametersInfo(Type t) 
        { 
            Console.WriteLine("***** GetParametersInfo *****"); 
            MethodInfo[] mi = t.GetMethods(); 
            foreach (MethodInfo m in mi) 
            { 
                // Get return value. 
                string retVal = m.ReturnType.FullName; 
                StringBuilder paramInfo = new StringBuilder(); 
                paramInfo.Append("("); 

                // Get params. 
                foreach (ParameterInfo pi in m.GetParameters()) 
                { 
                    paramInfo.Append(string.Format("{0} {1} ", pi.ParameterType,
                        pi.Name)); 
                } 
                paramInfo.Append(")"); 

                // Now display the basic method sig. 
                Console.WriteLine("->{0} {1} {2}", retVal, m.Name, paramInfo); 
            } 
            Console.WriteLine(""); 
        } 
    } 
}

输出

***** GetParametersInfo ***** 
->System.Int32 get_Speed () 
->System.Void Accelerate (System.Int32 accelerateBy ) 
->System.Boolean IsMoving () 
->System.Double calculateMPG (System.Int32 startMiles System.Int32 endMiles Syst 
em.Double gallons ) 
->System.String ToString () 
->System.Boolean Equals (System.Object obj ) 
->System.Int32 GetHashCode () 
->System.Type GetType ()

反射构造函数

GetConstractors() 函数返回一个 ConstractorInfo 元素数组,我们可以使用它来获取更多类构造函数信息。

// GetConstractorInfoDemo.cs 
using System; 
using System.Reflection; 

namespace Reflection 
{ 
    class GetConstractorInfoDemo 
    { 
        static void Main() 
        { 
            // Get name of type 
            Type t = typeof(Car); 
            GetConstructorsInfo(t); 

            Console.ReadLine(); 
        } 

        // Display method names of type. 
        public static void GetConstructorsInfo(Type t) 
        { 
            Console.WriteLine("***** ConstructorsInfo *****"); 
            ConstructorInfo[] ci = t.GetConstructors (); 
            foreach (ConstructorInfo  c in ci) 
                Console.WriteLine(c.ToString () ); 
            Console.WriteLine(""); 
        } 
    } 
}

输出

***** ConstructorsInfo ***** 
Void .ctor() 
Void .ctor(System.String, Int32)

Assembly 类

System.Reflection 命名空间提供了一个名为 Assembly 的类。我们可以使用这个 Assembly 类来获取有关程序集的信息并操作提供的程序集;这个类允许我们在运行时加载模块和程序集。Assembly 类联系 PE 文件以在运行时获取有关程序集的元数据信息。一旦我们使用这个 Assembly 类加载了程序集,我们就可以搜索程序集中的类型信息。还可以创建由 Assembly 类返回的类型的实例。

动态加载程序集

Assembly 类提供了以下方法在运行时加载程序集:

  • Load():这个静态重载方法以程序集名称作为输入参数,并在系统中搜索给定的程序集名称。
  • LoadFrom():这个静态重载方法接受程序集的完整路径,它将直接查找该特定位置,而不是在系统中搜索。
  • GetExecutingAssembly()Assembly 类还提供了另一个方法,使用 GetExecutingAssembly() 方法获取当前正在运行的程序集信息。此方法不重载。
  • GetTypes()Assembly 类还提供了一个很好的功能,称为 GetTypes 方法,它允许您获取相应程序集中定义的所有类型的详细信息。
  • GetCustomAttributes():此静态重载方法获取附加到程序集的属性。您还可以调用 GetCustomAttributes(),并指定第二个参数,该参数是一个 Type 对象,表示您感兴趣的属性类。
// AssemblyDemo.cs 
class AssemblyDemo 
{ 
    static void Main() 
    { 
        Assembly objAssembly; 

        // You must supply a valid fully qualified assembly name here.
        objAssembly = Assembly.Load("mscorlib,2.0.0.0,Neutral,b77a5c561934e089"); 

        // Loads an assembly using its file name   
        //objAssembly = Assembly.LoadFrom(
        //    @"C:\Windows\Microsoft.NET\Framework\v1.1.4322\caspol.exe"); 

        //this loads currnly running process assembly 
        // objAssembly = Assembly.GetExecutingAssembly(); 

        Type[] Types = objAssembly.GetTypes(); 

        // Display all the types contained in the specified assembly. 
        foreach (Type objType in Types) 
        { 
            Console.WriteLine(objType.Name.ToString()); 
        } 

        //fetching custom attributes within an assembly 
        Attribute[] arrayAttributes = 
        Attribute.GetCustomAttributes(objAssembly); 

        // assembly1 is an Assembly object 
        foreach (Attribute attrib in arrayAttributes) 
        { 
            Console.WriteLine(attrib.TypeId ); 
        } 

        Console.ReadLine(); 
    }
}

后期绑定

后期绑定是 .NET 反射中的一项强大技术,它允许您创建给定类型的实例并在运行时调用其成员,而无需对其存在进行编译时了解;此技术也称为 **动态调用**。当处理在编译时不可用的对象时,此技术才有用。在此技术中,开发人员负责在调用成员之前传递正确的成员签名;否则,将引发错误,而在早期绑定中,编译器会在调用成员之前验证成员签名。由于性能问题,在决定何时调用和使用此技术以及何时不使用此技术时,做出正确的决定非常重要。使用此技术会影响应用程序的性能。

// LateBindingDemo.cs 
using System; 
using System.Reflection; 

namespace Reflection 
{ 
    class LateBindingDemo 
    { 
        static void Main() 
        { 
            Assembly objAssembly; 
            // Loads an assembly  
            objAssembly = Assembly.GetExecutingAssembly(); 

            //get the class type information in which late bindig applied 
            Type classType = objAssembly.GetType("Reflection.Car");

            //create the instance of class using System.Activator class 
            object  obj  =  Activator.CreateInstance(classType); 

            //get the method information 
            MethodInfo mi = classType.GetMethod("IsMoving"); 

            //Late Binding using Invoke method without parameters 
            bool isCarMoving; 
            isCarMoving= (bool) mi.Invoke(obj, null); 
            if (isCarMoving) 
            { 
                Console.WriteLine("Car Moving Status is : Moving"); 
            } 
            else 
            { 
                Console.WriteLine("Car Moving Status is : Not Moving"); 
            } 

            //Late Binding with parameters 
            object[] parameters = new object[3]; 
            parameters[0] = 32456;//parameter 1 startMiles 
            parameters[1] = 32810;//parameter 2 end Miles 
            parameters[2] = 10.6;//parameter 3 gallons 
            mi = classType.GetMethod("calculateMPG"); 
            double MilesPerGallon; 
            MilesPerGallon= (double ) mi.Invoke(obj, parameters); 
            Console.WriteLine("Miles per gallon is : " + MilesPerGallon); 

            Console.ReadLine(); 
        } 
    } 
}

输出

Car Moving Status is : Not Moving 
Miles per gallon is : 33.3962264150943

反射发射

反射发射 支持在运行时动态创建新类型。您可以定义一个程序集以动态运行或将其自身保存到磁盘,还可以定义模块和新类型以及可以调用其方法的类型。

结论

.NET 中的反射非常庞大。本文不可能涵盖整个 API。但是,学习其中一部分将使您对 .NET 中的反射有全面的了解。

感谢您阅读我的文章。我希望您非常喜欢它。

© . All rights reserved.