有没有办法使用字符串作为类名来动态创建对象?
我已经离开VB好几年了,但是为了解决另一种语言的问题,我不得不在这个中开发一个包装器。我有一个工厂方法,可以根据其他地方的输入动态创建和返回一个类型的对象。提供的输入是从中创建对象的类名。正常语法意味着必须明确拼写整个类。要做到这一点,实际上可能有数百个if / then或者case来处理引用的libs中所有可用的类/对象选择:
If c_name = "Button" then obj = new System.Windows.Forms.Button
If c_name = "Form" then obj = new System.Windows.Forms.Form
....
我希望将所有这些案例处理减少到一行:IE ...
my_class_name = "whateverclass"
obj = new System.Windows.Forms.my_class_name()
在PHP中,这样处理......
$my_class_name = "whateverclass";
$obj = new $my_class_name();
编辑:看一些答案,我想我已经在我的脑海里了。尽管我对this CreateInstance更感兴趣,包括提供构造参数,我确实设法使用Assembly类的this variation giving more options方法变体来使其工作...
my_type_name = "System.Windows.Forms.Button"
asmb_name = "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
button1 = Reflection.Assembly.Load(asmb_name).CreateInstance(my_type_name)
换句话说,它需要一种方法来做到这一点,而不是任何固有的语言语法?使用完整的汇编字符串和类路径时,This Activator variation也起作用。我怀疑CreateInstance可能没有完全的能力让我像对待正常一样对待对象,即obj = new System.Windows.Forms.Button
。这就是为什么我不能简单地使用CreateObject
。如果没有允许您用字符串替换字符串的自然语言功能,是否有人能够了解使用CreateInstance
可以获得哪些限制?
另外,基本的Activator.CreateInstance(在Unwrap之后)和Assembly.CreateInstance方法之间是否存在差异?
答案 0 :(得分:10)
这可能会做你想要/测试的工作;切换顶部的类型注释以查看。
Imports System.Reflection
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Dim fullyQualifiedClassName as String = "System.Windows.Forms.TextBox"
Dim fullyQualifiedClassName As String = "System.Windows.Forms.Button"
Dim o = fetchInstance(fullyQualifiedClassName)
' sometime later where you can narrow down the type or interface...
Dim b = CType(o, Control)
b.Text = "test"
b.Top = 10
b.Left = 10
Controls.Add(b)
End Sub
Private Function fetchInstance(ByVal fullyQualifiedClassName As String) As Object
Dim nspc As String = fullyQualifiedClassName.Substring(0, fullyQualifiedClassName.LastIndexOf("."c))
Dim o As Object = Nothing
Try
For Each ay In Assembly.GetExecutingAssembly().GetReferencedAssemblies()
If (ay.Name = nspc) Then
o = Assembly.Load(ay).CreateInstance(fullyQualifiedClassName)
Exit For
End If
Next
Catch
End Try
Return o
End Function
答案 1 :(得分:3)
我很确定Activator用于远程处理。你想要做的是使用反射来获取constor并在这里调用它是一个例子http://www.eggheadcafe.com/articles/20050717.asp
我认为您遇到的问题是您的程序集是GetType用来尝试查找Button的程序集。您需要从正确的程序集中调用它。
这应该这样做
Dim asm As System.Reflection.Assembly = System.Reflection.Assembly.LoadWithPartialName("System.Windows.Forms")
Dim obj As Object = Activator.CreateInstance(asm.GetType("System.Windows.Forms.Button"))
答案 2 :(得分:0)
看一下Activator.CreateInstance(Type)方法。
如果您的输入是一个类的名称,您应该能够这样做:
Dim obj As Object = Activator.CreateInstance(GetType("Name_Of_Your_Class"))
您必须调整GetType调用以确保为其提供足够的信息,但在大多数情况下,只需要该类的名称即可。
答案 3 :(得分:0)
这是我在通过互联网搜索时发现的一种非常简单的方法:
require 'time'
Time.parse("2016-03-02T17:27:32.000+00:00")
=> 2016-03-02 17:27:32 +0000