Dynamic loading and use type

xiaoxiao2021-03-06  84

Author: Microsoft

Reflection delivers the underlying structure such as Microsoft Visual Basic.Net and JScript language compiler to implement implicit binding. The binding is the process of positioning a declaration corresponding to a particular type. When this process occurs when it is running, it is called after the compilation. Visual Basic.net allows you to use hidden bindings in your code; VisualBasic.Net compiler calls the Helper method, use the Reflection to get the object type. Parameters passing to the Helper method make the appropriate method to be called at runtime. These parameters are the instance of the call method (object), the name of the called method (string), and the parameters passed to the called method. (An array of objects).

In the following code example, the Visual Basic.NET compiler is implicitly invited by Reflection to call the object call method when compiling. The HelloWorld class has a Printhello method that can print "Hello World" and some text passed to the PrintHello method. In this example, the PrintHello method call is actually type. InvokeMember; Visual Basic code allows the PrintHello method to be called, as if the object's type (HelloBj) is already known (previous binding), not at runtime (after tie set).

[Visual Basic]

Imports system

Module Hello

Sub main ()

'Set Up variable.

Dim Helloobj As Object

'Create the Object.

Helloobj = new helloworld ()

'Invoke The Print Method As if it Was Early Bound

'Even though it's really late bound.

Helloobj.Printhello ("Visual Basic Late Bound")

End Sub

End module

Custom binding

In addition to the compiler, REFLECTION can also be used in the code to complete the binding.

Common Language Runtime supports multiple programming languages, which are boundless in these languages. In the case of the previous binding, the code generator can fully control the binding. However, in the reactation of the reflection, the binding must be controlled by custom binding. The Binder class provides a member to select a custom control with the call.

Using custom bindings, you can load assembly in runtime, get information about type, indicate the type of you, and call methods, access fields, or type properties. If you don't know the type of object, this technology is particularly useful, for example, when the object type is dependent on the user input. The code in the following example shows the method that is dynamically used in HelloWorld.dll Assembly, the first one in Visual Basic.net, the second in C #.

[Visual Basic]

'This class is deployed as an assembly consisting hello world string.

Private m_helloworld as string = "HelloWorld"

'Default Public Constructor.

Public Sub New ()

End Sub 'NEW

'Print "Hello World" Plus thesssed text.public Sub PrintHello (txt as string)

'Output to the console.

Console.WriteLine (M_HelloWorld & "& txt))

End Sub

END CLASS

Imports system

Imports system.reflection

Module VisualBasiclateHello

Sub main ()

'Set up the variables.

Dim assem as system.reflection.assembly

DIM OBJ AS Object

Dim Hellotype As Type

Dim PrintMethod As MethodInfo

'Load the assembly to use.

askEM = System.Reflection.Assembly.Load ("HelloWorld")

'Get the type to use from the assembly.

Hellotype = askEM.GETTYPE ("HelloWorld")

'Get the method to use from the type.

PrintMethod = Hellotype.getMethod ("Printhello")

'Create an Instance of the Type.

Obj = activator.createInstance (Hellotype)

'Create an Array to Hold The Arguments.

DIM ARGS (1) As Object

'Set the arguments.

args (0) = "from visual basic late bound"

'Invoke the Method.

PrintMethod.invoke (Obj, Args)

End Sub

End module

The following is C # version:

[C #]

// this class is deployed as an assembly consisting of one DLL,

// Called HelloWorld.dll.

Using system;

Public class helloworld {

// constant hello world string.

Private const string m_helloWorld = "Hello World";

// Default public constructor.

Public helloworld () {

}

// Print "Hello World" Plus the Passed Text.

Public void printhello (string txt) {

// output to the console.

Console.writeLine (M_HelloWorld " TX);

}

}

// illustrates reflection's late binding functionality.

// Calls the Printhello Method ON A Dynamically Loaded

// and created instance of the helloworld class.

Using system;

Using system.reflection; public class csharplatehello {

Public static void main () {

// load the assembly to us.

AskEMBLY ASSEM = askMBLY.LOAD ("HelloWorld");

// Get the Type to use from the assembly.

TYPE Hellote = askEM.GETTYPE ("HelloWorld");

// Get the method to call from the Type.

MethodInfo PrintMethod = Hellotype.getMethod ("Printhello");

// Create An Instance of The HelloWorld Class.

Object obj = activator.createInstance (Hellotype);

// CREATE The args array.

Object [] args = new object [1];

// set the arguments.

Args [0] = "from csharp late bound";

// Invoke the printhello method.

PrintMethod.invoke (OBJ, ARGS);

}

}

InvokeMember and CreateInstance

You can use Type.InvokeMember to call a type of member. Various classes of CreateInstance methods, such as System.Activator, and System.Reflection.assembly, are the special form of InvokeMember for generating a type of instance. Binder classes are used in these methods for overloading parsing and parameter conversion.

The code in the following example shows three possible parameter translations and a combination of members selected. In CASE1, parameter conversion or member selection is not required. In CASE 2, you only need members to choose. In CASE3, only parameter conversion is required.

[C #]

Public Class CustomBinderdriver

{

Public static void main (String [] arguments

{

Type T = TypeOf (CustomBinderDriver);

CustomBinder Binder = New CustomBinder ();

Bindingflags flags = bindingflags.invokeMethod | BindingFlags.instance |

Bindingflags.public | bindingflags.static;

// Case 1. Neither Argument Coercion Nor Memberselection is needed.

Args = new object [] {};

T. InvokeMember ("PrintBob", Flags, Binder, NULL, ARGS);

// Case 2. Only Member Selection is needed.

Args = new object [] {42};

T. Invokemember ("PrintValue", Flags, Binder, NULL, ARGS;

// Case 3. Only Argument COERCION IS NEEDED.

Args = New Object [] {"5.5"};

T. InvokeMember ("PrintNumber", Flags, Binder, Null, Args;

Public static void printbob ()

{

Console.WriteLine ("PrintBob");

}

Public Static Void PrintValue (Long Value)

{

Console.writeline ("PrintValue ({0})", Value);

}

Public Static Void PrintValue (String Value)

{

Console.writeline ("PrintValue /" {0} / ")" ", value);

}

Public Static Void PrintNumber (Double Value)

{

Console.writeline ("PrintNumber ({0})", Value);

}

}

When there is more than one member member, there is a need to have an overload analysis. Binder.bindtomethod and Binder.bindtofield methods can be used to bind to a member. Binder.bindTomethod can also provide attribute analysis via GET and SET property.

BindTomethod returns MethodBase that can be called. Returns null if there is no call. If you can't call, BindTomethod returns MethodBase to call or NULL. MethodBase Return Value No need to be one of the Match parameters, although the fact is often.

The caller may want to get the return of the BYREF parameter. So, if the Bindto method changes the parameter array, Binder allows the customer to make the parameter array back to its original form. In order to achieve this, the caller must ensure that the parameter order is unchanged. When the parameters are passed by the name, Binder re-organs the parameter group for the call.

Available members refer to those members defined in the type or any basic type. If bindingFlags.nonpublic, any access level member will return. If bindingflags.nonpublic is not indicated, Binder must perform access rules. When you specify the public or nonpublic binding flag, you must also specify the instance or static flag, otherwise there will be no members return.

If only one member corresponds to the name, it does not need a callback, and it is completed to the binding of this method. The code example in CASE 1 indicates this: there is only one available PrintBob method, so you don't need a callback.

For example, more than one member is available. All of these methods are passed to the Bindto method, and then choose the appropriate method and return. In the code example in CASE 2, there are two methods called PrintValue. The appropriate method depends on the bindtomethod call.

ChangeType performs parameter conversion, which transforms the actual parameter to the parameter type of the selected method. Even if the type is perfectly matched, ChangeType is also called for each parameter.

In the code example in CASE 3, an actual parameter of the String type value "5.5" is passed to the method in the formal parameter Double type. To call success, string value "5.5" must be converted to a Double value. ChangeType performs this transformation.

ChangType only performs no loss conversion, as shown in the following table:

Source Type Target Type

Any Type ITS Base Type

Any Type Interface IT IT ITMENTS

Char uint16, uint32, int32, uint64, int64, single, double

Byte char, uint16, int16, uint32, int32, uint64, int64, single, douplasbyte int16, int32, int64, single, double

UINT16 UINT32, INT32, UINT64, INT64, SINGLE, DOUBLE

INT16 INT32, INT64, SINGLE, DOUBLE

UINT32 UINT64, INT64, SINGLE, DOUBLE

INT32 INT64, SINGLE, DOUBLE

Uint64 Single, Double

INT64 SINGLE, DOUBLE

Single Double

Non-Reference Type Reference Type

The Type class has a get method that resolves the reference to a member using the Binder type parameter. Type.getConstructor, Type. GetMethod, and Type.getProperty finds the member by providing signature information for a member. They call binder.selectmethod and binder.selectproperty to select the signature information for the appropriate method.

转载请注明原文地址:https://www.9cbs.com/read-98539.html

New Post(0)