📜  在C#中使用反射进行后期绑定

📅  最后修改于: 2021-05-29 13:41:13             🧑  作者: Mango

上面主题中出现的两个主要术语是“后期绑定”和“复制”。因此,让我们首先定义这两个术语。在运行时对方法和对象的绑定称为“后期绑定”或“动态绑定” 。反射是程序集检查其元数据的能力。元数据包含程序集中数据的信息。
反射用于实现后期绑定,因为它允许您使用编译时不可用的代码。我们将在以下代码段中看到其示例。

示例1:在此程序中,我们使用了后期绑定,因为我们不了解必须在编译时实例化的类的知识。声明一个名为Assembly类的执行对象,并使用GetExecutingAssembly方法加载当前Assembly。接下来,我们必须找到稍后要实例化的类的类型,即Student 。为此,请在Assembly类的对象上使用GetType方法,并将类型存储在另一个名为StudentType的对象中。 GetType方法需要一个String参数,在这种情况下,该参数是类的完整名称LateBinding.Student。由于该类型在程序中此时是未知的,因此我们使用Type类来声明studentType 。现在,我们使用使用类型作为参数的CreateInstance方法创建studentType的实例。 Activator类包含用于在本地或远程创建对象类型或获取对现有远程对象的引用的方法。接下来,创建一个MethodInfo对象,并使用GetMethod方法存储信息。将方法名称作为参数传递给GetMethod 。要调用GetDetails,请使用MethodInfo对象调用Invoke方法,并将studentObject作为参数传递。最后,使用String det显示详细信息,并定义类。

// C# program to show the Late 
// Binding using Reflection
using System;
using System.Reflection;
  
namespace LateBinding {
  
class Program {
  
    // Main Method
    static void Main(string[] args)
    {
        // Declare Instance of class Assembly
        // Call the GetExecutingAssembly method 
        // to load the current assembly
        Assembly executing = Assembly.GetExecutingAssembly();
  
        // To find the type of the Class Student
        Type studentType = executing.GetType("LateBinding.Student");
  
        // Create an Instance of the Student type
        object studentObject = Activator.CreateInstance(studentType);
  
        // Store the info of the method in an object
        // of class MethodInfo
        MethodInfo getMethod = studentType.GetMethod("GetDetails");
  
        // To store the parameters required
        // by Method GetDetails
        String[] param = new String[2];
        param[0] = "1";
        param[1] = "Lisa";
  
        // To display the result of the method
        String det = (String)getMethod.Invoke(studentObject, param);
        Console.WriteLine("Student Details : ");
        Console.WriteLine("Roll Number - Name \n{0}", det);
  
    } // end Main
  
} // end Program
  
  
public class Student {
  
    public String GetDetails(String RollNumber, String Name)
    {
        return RollNumber + " - " + Name;
    }
  
} // end Student
  
}

输出:

Student Details : 
Roll Number - Name 
1 - Lisa

注意:在上面的代码中,如果不定义类并构建代码,则由于编译时未完成绑定,因此它将成功构建。但是,当您运行它时,您将得到一个错误,因为它将仅在运行时遇到。错误消息将如下所示;

示例2:另一个类似的示例是下面给出的具有Shape类的代码,我们将后期绑定shapeName方法。

// C# program to show the Late 
// Binding using Reflection
using System;
using System.Reflection;
  
namespace Geometry {
  
// class Shape
public class Shape {
  
    // Function that gives the name of the 
    // shape based on the number of sides
    // the number of sides is a string that
    // contains the value
    public String shapeName(String sideNumber)
    {
        if (sideNumber == "0" || sideNumber == "1" || sideNumber == "2")
            return "Not Valid";
        else if (sideNumber == "3")
            return "Triangle";
        else if (sideNumber == "4")
            return "Quadrilateral";
        else
            return "Polygon";
    }
  
} // end Shape
  
class Program {
  
    // Main Method
    static void Main(string[] args)
    {
        // Object of Assembly class
        Assembly exceutable = Assembly.GetExecutingAssembly();
  
        // To find the type of the class
        Type shapeType = exceutable.GetType("Geometry.Shape");
  
        // To create an instance of Shape class
        // without prior information about it
        object shapeObject = Activator.CreateInstance(shapeType);
  
        // To find the info about the method
        MethodInfo shapeNameMethod = shapeType.GetMethod("shapeName");
  
        // Prepare parameters for the method
        String[] param = new String[1];
        param[0] = "4";
  
        // To invoke the method using Invoke
        String sName = (String)shapeNameMethod.Invoke(shapeObject, param);
  
        // To  display the name of the shape
        Console.WriteLine("Name of the Shape is {0}", sName);
  
    } // end Main
  
} // end Program
  
}
输出:
Name of the Shape is Quadrilateral

注意:后期绑定的缺点是,如果在方法或类的名称中出现任何拼写错误,编译器将在编译时无法识别它,因此代码将成功构建。在大多数实际情况下,使用“早期绑定”而不是“后期绑定”。