Reflection principle and Introduction

A. What is reflected

 Reflection, the Chinese translation for reflection. This is the way to get the type of information in the .Net runtime,

.Net applications of several parts: 'Assembly (Assembly)', 'module (Module1)', 'type (class)' composition, is reflected to provide a way of programming, the programmer can program at runtime get information about these components,

For example: Assembly class information can be obtained assembly is running, it can also dynamically load an assembly, and concentrated in the program to find the type of information, and create an instance of that type.

Type class type information object can be obtained, this object contains all the information elements: methods, constructors, properties, etc., these elements can be obtained by the information Type class, and calls it.

The method comprising MethodInfo information can be obtained name of the method, the class parameters, return values, and it can be called. And so on,

There FieldInfo, EventInfo and so on, these classes are included in the System.Reflection namespace.

 II. Relationship between the assembly and namespace

Many people on this concept may still be quite clear, qualified for .Net programmers, it is necessary to clarify this point.

.NET assembly is a minimum unit of application execution, the compiled assemblies are .dll and .exe. The relationship between the assembly and namespace is not one to one, nor each other, an assembly which can have multiple namespaces, a namespace can exist in multiple programs, it may be a bit vague to say, for example:

Assembly A contains two namespaces:

namespace  N1
{
      public   class   AC1 {...}
       public   class   AC2 {...}
}
namespace  N2
{
      public   class   AC3 {...}
       public   class   AC4 {...}
}

Assembly B comprises two namespaces:

namespace  N1
{
      public   class   BC1 {...}
       public   class   BC2 {...}
}
namespace  N2
{
      public  class  BC3  {…}
      public  class  BC4{…}
}

Both programs focus N1 and N2 have two namespaces, and each declares two classes, this is entirely possible, then we refer to a set of application program A, then this application, we N1 can see the following classes of AC1 and AC2, N2 following classes of AC3 and AC4.

Then we remove the reference to A and B together with a reference, then in this application we can see into the following classes N1 BC1 and BC2, N2 below the same. If we also references the two assemblies, then N1 below we can see four categories: AC1, AC2, BC1 and BC2.

Here, we can understand a concept, the namespace is simply stated that a type family, such as some people are Han Chinese, someone is Muslim; and the assembly showed that a type of live, such as someone living in Beijing, was living in Shanghai ; then in Beijing Han people, there are Hui people, Shanghai Han Chinese people, but also the Muslim people, this is not contradictory.

We said above, the assembly is a type of place of residence, then in a program to be used in a class, you must tell the compiler that this class live child, the compiler can find it, that must reference the assembly.

 So if in the preparation of procedures, perhaps not sure where this class, just know its name, you can not use it? The answer is yes, and this is reflected, to provide the type of address when the program is running, try to find it.

 

 III. Why reflection

 Some people have questions about the program can be used in classes since pre-written, then why go to generate when the program is running, this not a waste of system resources. There is reasonable, since Microsoft gave us develop this technology, there is certainly demand this, this thing, give a simple example:

Now to develop a report printing module, some companies require data to Excel report, and some companies require print Crystal reports, etc., this time we can first define an interface, any report printing method must implement this interface:

 

   public  interface   IReport
    {
        void StartPrint();
    }

We can load profile corresponding to the type of report to read, since the report printing IReport class implements an interface, it can be converted to the intensity of reflection by way of the interface type, this can be achieved without modifying the underlying code can be achieved print different data reporting, in line with the principle of opening and closing i have my programming, this is a reflection of the most classic application.

static class Factory's public
{
// [1] reads the configuration file
static String reportType ConfigurationManager.AppSettings = [ "the ReportType"] the ToString ();.
// [2] using the reflection to create an object class implements the interface and the interface to return type
public the IReport ChooseReportType static ()
{
return (the IReport) the Assembly.Load ( "UseFactory") the CreateInstance ( "UseFactory." reportType +);.
}
}

IV. How to use reflection to get the type

There are two ways to obtain such information:

The first way to give instantiate the object. The times I just get this instance of the object, the object may be a reference to get in the way, perhaps a reference to an interface, but I do not know its exact type, I need to know, then you can call System.Object GetType method on the statement to obtain an instance of an object type of object, such as in a way, I need to determine whether the parameters passed in to achieve a certain interface, if realized, a method of this interface is called.

   public void Progress(object o)
        {
            Type objType = o.GetType();

            if (objType.GetInterface("ITest") !=null)
            {
                // call the method of the interface 
            }
        }

The second way is to get the type of Assembly.GetType by Type.GetType and methods, but when using this method we need to pay attention to some problems. B.dll reflection type requires the assembly in the assembly in A.dll. If you use the slightest mistake, it will generate a runtime error. For example Type.GetType ( "BNameSpace.ClassName") set in the program type B.dll A.dll acquisition assembly is, it returns Null.

About reflection across the assembly, there are two points to note:

1, if typeof, compiled by, reflected across the assembly will be able to operate normally. It can be said, typeof support strongly typed. such as

 Type supType = typeof(BNameSpace.SubSpace.Class);

If the current assembly does not add a reference to EnterpriseServerBase.dll, the compiler will complain.

2, if the reflection is performed using Type.GetType words, the situation is more complicated. This is because the non-Type.GetType strongly typed. Type.GetType parameter is a string type for the fully qualified name, if the target type when the current string is not represented assembly, Type.GetType runtime returns null. The solution is: first load the target assembly, and then use Assembly.GetType way to get the type. Such as:

Assembly asmb = Assembly.LoadFrom("EnterpriseServerBase.dll") ;
Type supType = asmb.GetType("EnterpriseServerBase.DataAccess.IDBAccesser") ;

Note: When using Type.GetType time, even if you add a reference to the EnterpriseServerBase.dll, Type.GetType ( "EnterpriseServerBase.DataAccess.IDBAccesser") will return null, because only in the current assembly Type.GetType the type of search conducted.

5. How to dynamically create objects based on the type

The first way

public class Example
{
    static void Main()
    {
        // Create an instance of the StringBuilder type using 
        // Activator.CreateInstance.
        Object o = Activator.CreateInstance(typeof(StringBuilder));

        // Append a string into the StringBuilder object and display the 
        // StringBuilder.
        StringBuilder sb = (StringBuilder) o;
        sb.Append("Hello, there.");
        Console.WriteLine(sb);

        // Create an instance of the SomeType class that is defined in this 
        // assembly.
        System.Runtime.Remoting.ObjectHandle oh = 
            Activator.CreateInstanceFrom(Assembly.GetEntryAssembly().CodeBase, 
                                         typeof(SomeType).FullName);

        // Call an instance method defined by the SomeType type using this object.
        SomeType st = (SomeType) oh.Unwrap();

        st.DoSomething(5);
    }
}

 

Example Two: creating an object has a configuration parameter

namespace  TestSpace  
{
  public  class  TestClass
      {
      private  string  _value;
      public  TestClass(string  value)  
    {
      _value=value;
      }
  }
}

Type  t  =  Type.GetType(“TestSpace.TestClass”);
Object[]  constructParms  =  new  object[]  {“hello”};  //构造器参数
TestClass  obj  =  (TestClass)Activator.CreateInstance(t,constructParms);

The parameters in order to put an Object array

6. How to obtain the method and dynamic method invocation

Examples of dynamic method call applications reflected as follows:

using System;
using System.Reflection;

class Program
{
    // Methods to get:

    public void MethodA(int i, int j) { }

    public void MethodA(int[] i) { }

    public unsafe void MethodA(int* i) { }

    public void MethodA(ref int r) {}

    // Method that takes an out parameter:
    public void MethodA(int i, out int o) { o = 100;}


  static void Main(string[] args)
  {
    MethodInfo mInfo;

    // Get MethodA(int i, int j)
    mInfo = typeof(Program).GetMethod("MethodA",
        BindingFlags.Public | BindingFlags.Instance,
        null,
        CallingConventions.Any,
        new Type[] { typeof(int), typeof(int) },
        null);
    Console.WriteLine("Found method: {0}", mInfo);

    // Get MethodA(int[] i)
    mInfo = typeof(Program).GetMethod("MethodA",
        BindingFlags.Public | BindingFlags.Instance,
        null,
        CallingConventions.Any,
        new Type[] { typeof(int[]) },
        null);
    Console.WriteLine("Found method: {0}", mInfo);

    // Get MethodA(int* i)
    mInfo = typeof(Program).GetMethod("MethodA",
        BindingFlags.Public | BindingFlags.Instance,
        null,
        CallingConventions.Any,
        new Type[] { typeof(int).MakePointerType() },
        null);
    Console.WriteLine("Found method: {0}", mInfo);

    // Get MethodA(ref int r)
    mInfo = typeof(Program).GetMethod("MethodA",
        BindingFlags.Public | BindingFlags.Instance,
        null,
        CallingConventions.Any,
        new Type[] { typeof(int).MakeByRefType() },
        null);
    Console.WriteLine("Found method: {0}", mInfo);

    // Get MethodA(int i, out int o)
    mInfo = typeof(Program).GetMethod("MethodA",
        BindingFlags.Public | BindingFlags.Instance,
        null,
        CallingConventions.Any,
        new Type[] { typeof(int), typeof(int).MakeByRefType() },
        null);
    Console.WriteLine("Found method: {0}", mInfo);

  }
}
For more information on GetMethod () can be achieved by the following:

https://docs.microsoft.com/en-us/dotnet/api/system.type.getmethod?view=netframework-4.8

7. How to dynamically get property information:

The following simple example illustrates how to obtain attribute information

 void GetProperty()
        {
            Type objType = typeof(string);
           PropertyInfo[]  obj =  objType.GetProperties();
           if (obj !=null)
           {
               foreach (var item in obj)
               {
                   this.textBox1.Text = this.textBox1.Text + item.Name.ToString() + "\r\n";
               }
           }
        }

 

Guess you like

Origin www.cnblogs.com/Artist007/p/11022495.html