Create an object from a string dynamic from a string during .NET

zhaozj2021-02-11  191

Seeing the title, most of them say "Creating Objects at runtime" is not a pediatrics, just like this:

DIM newbutton as button = new button ()

NewButton.name = "Button1"

This is indeed created a button at runtime. However, if you need to create a button according to the user, how to do the check box or radio box, it seems to be good:

Dim NewControl As Control

SELECT CASE USERSELECTION

Case "button"

NewControl = New Button ()

Case "checkbox"

NewControl = New Checkbox ()

....

End SELECT

If the user needs dozens of controls inside Windows.Forms, do you want to write doors? Of course, I don't want to do this kind of user, but the demand is always a variety of diverse. If there is a way to specify the type of creation of the object at runtime, even the string of the name of the name is created. Object, how easy it is. The reflection mechanism of .NET FRAMWORK has brought us a solution to the problem. Here, if you only need to create a general object, we can implement it via System.Activator, and more complicated we can implement the constructor.

Reflection reflection is an important mechanism in .NET, many people have already introduced the reflection, let's simply review it. By reflex, you can get a member of each type (including class, structure, delegate, interface, enumeration) in runtime, including methods, properties, events, and constructor, etc., you can also get the name of each member. Limits and parameters, etc. With the reflection, you can make each type of refer to each type. If you get the information of the constructor, you can create objects directly, even if the type of this object is not known when compiling.

Before working on the task of creating a control, let's take a simple example, build a Windows program called VBAppliction, add a new file, enter a new class:

Public class myclasstest

Private Myfield As String

Public Sub New ()

Myfield = "hi!"

End Sub

Public Sub Hello ()

Console.writeline (Myfield)

End Sub

END CLASS

Then add it to the form into a new button, enter the following event code:

'method one

DIM T as type = gettype (myclasstest)

o = system.activator.createInstance (T)

O.hello ()

The first line getType (MyClassTest) function has obtained the type object of the class we created (using the TypeOf function in C #). Next, we use a static method createInstance of the System.Activator class CreateInstance to create an object instance and assign the object reference to O. Activator is a tool for creating a local or remote object. Run this program, we can see the result of the WriteLine function run from the Commond Window from the COMMOND WINDOW. You can see the correctly established object.

If we use the class with a complicated constructor, you can also use the constructor to create the required object, the code is as follows:

'Method Two

DIM T as type = gettype (myclasstest) DIM C as system.reflection.constructorinfo

DIM TYPES () As Type

Redim Types (-1)

c = T.getConstructor (Reflection.BindingFlags.instance_

Or Reflection.BindingFlags.public, _

Nothing, reflection.callingconventions.hasthis, types, nothing

DIM params () as Object

REDIM params (-1)

o = c.invoke (params)

O.hello ()

Here we create an object of System.Reflection.ConstructorInfo, which can obtain information about the class constructor. We use the GetConstructor method of the Type class to search for the available constructor.

What needs to be explained is a Types () array, this array is the parameter type table used by the search constructor. Our constructor has no parameters, so you need an array that is empty but not for Nothing (NULL in C #). Redim types (-1) is the statement to establish this array, written in C #:

Types = New Type [0];

If the construction method is like this:

Public Sub New (BYVAL A AS Integer, B AS String)

Then the corresponding Types array should be

DIM TYPES (1) as Type

Types (0) = getType (int32)

Types (1) = getType (String)

Reflection.bindingFlags.instance and Reflection.BindingFlags.public are a bit shield, which is an option to specify a search.

The params () array is the parameter content table of the constructor, which is the same because there is no parameters, we use the redim -1 syntax.

The Invoke method performs a constructor and creates an object instance.

Now we return to the first implementation method, change the code, will

DIM T as type = gettype (myclasstest)

Change to

DIM T as type = type.gettype ("vbapplication.myclasstest")

The result of run has not changed, this is to say that we have implemented an object from a string! However, the use of the GetType method is limited, and let's talk about us. Now we can realize our desire: dynamically create controls. Through the above knowledge, we easily write a subroutine that dynamically creates a window control:

Private Function CreateNewControls (ByVal targetControls As Control.ControlCollection, ByVal ctlName As String, ByVal ctlType As Type, ByVal ctlSize As Drawing.Size, ByVal ctlLocation As Drawing.Point) As Control

DIM TOCREATE AS Control

TOCREATE = ctype (system.activator.createinstance (ctltype), control)

TOCREATE.NAME = CTLNAME

TOCREATE.SIZE = CTLSIZE

TOCREATE.LOCATION = CTLOCATION

TargetControls.Add (Tocreate)

Return Tocreate

END FUNCTION

The longer statement contains all the contents in the previous example. If you write with C #, you can write it.

TOCREATE = (Control) System.activator.createInstance (CTLTYPE);

We change the event process of the button:

DIM C As Control = Me.createNewControls1 (Me.Controls, "Control1", Gettype (Checkbox), New Size (168, 40), New Point (64, 176))

C.Text = "New Creation"

Now, click the button to see a new Checkbox appear on the window, the title is New Creation, and if the event process is written, you can add an event response for the new control.

It seems that everything is achieved? Note that getType (Checkbox) or the literal representation of the class name, cannot reach the function of creation of objects with strings. If we change this to Type.gettype ("System.Windows.Forms.Checkbox") Well, test, huh, huh, I have fallen. Why is this this? The Type.getType () method is limited to the type of strings or types in the Corlib or the types of the project. If it is from the external assembly, you need to add the name of the assembly. The Windows.Forms assembly is a public assembly, which is located in the program set cache, which can be implemented inside the .NET FRAMWORK. Side by Side execution. So this assembly has a different version. In order to determine the version of the version, we must not only provide the name of the assembly, but also provide the version and strong name of the assembly. According to this idea, on the .NET Framework 1.1, write this sentence into type.gettype ("System.Windows.Forms.Checkbox, System.Windows.Forms, Version = 1.0.5000.0, Culture = neutral, publickeyToken = B

77A

5C

561934E089 "). There is no problem now. The problem is how we get the version and strong name of the Windows.Forms assembly used? You can use the syntax of gettype (checkbox) .AssemblyqualifiedName, we can get this information, we can This information is used for any other control because they all come from the same version of the Windows.Forms assembly. You can now play a fun, put a text box to the window, such as called TextBox1, change the button's event process to:

Try

DIM C As Control = Me.createNewControls1 (Me.Controls, "Control1", Type.GetType ("System.Windows.Forms." & TextBox1.text & ", System.Windows.Forms, Version = 1.0.5000.0, Culture = neutral, publickeytoke = b

77A

5C

561934E089 "), New Size (168, 40), New Point (64, 176))

C.Text = "New Creation" Catch EX AS EXCEPTION

MSGBOX (ex.Message)

END TRY

Now as long as you type "button" in TextBox, press the button, a new button is generated! If you entered Checkbox, a check box will be generated. No matter how hard is the user, the control can "create" on demand ". The reflective mechanism has many uses in .NET, it is said that functions such as class references and virtual constructors in delphi.net are used for .NET FRAMWORK is achieved by means of reflection and system.Type types, making this tool will give Your program has a lot of color.

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

New Post(0)