有什么方法可以通过反射实现基于枚举的新类?
基本上我想删除Select Case。我有很多Enum和建设者......
例如:
Public MustInherit Class GeneralClass
'...
Enum GeneralClassType
A = 1
B = 2
End Enum
Public Shared Function BuildClass(Val as Integer, ParamArray par() as Object) as GeneralClass
Dim NewObject as GeneralClass = Nothing
Select Case Ctype(Val, GeneralClassType)
Case GeneralClassType.A
NewObject = new A
Case GeneralClassType.B
NewObject = new B
Case else
throw new exception("invalid type.")
end select
NewObject.setPar(par)
return NewObject
end function
End Class
Public Class A
Inherits GeneralClass
'...
End Class
Public Class B
Inherits GeneralClass
'...
End Class
函数 BuildClass 根据类型和参数从数据库构建一个类。 但我需要让Case创建一个新类型的实例。
我知道我可以通过反射来实例化一个类,但前提是你知道最终的类型。 有没有办法做这个dinamicy,比如在数据库中保存类名?
public function InstantiateClass(of T)() as T
Dim NewObject as GeneralClass = GetType(T).GetConstructor(New Type() {}).Invoke(New Object() {})
return NewObject
end class
比我能得到像
这样的东西Dim Var1 as GeneralClass = InstantiateClass(of A)()
并在Build函数中使用此实例。但在这里我需要知道Type A
BaseTest示例,使用枚举名称。
Public Class Form1
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim BaseFlag As Integer = 2
Dim BaseName As String = "Create a class from enum"
Dim T As BaseTest = BaseTest.Build(BaseFlag, BaseName)
MsgBox(T.GetClassTypeName)
End Sub
End Class
Public MustInherit Class BaseTest
Protected Name As String
Enum TestType
TestA = 1
TestB = 2
TestC = 3
End Enum
Public Function GetClassTypeName() As String
Return String.Concat(Name, ". The final class is: ", Me.GetType.FullName, "")
End Function
Public Shared Function Build(BaseFlag As Integer, Name As String) As BaseTest
Dim NS As String = GetType(BaseTest).FullName
Dim Index As Integer = NS.LastIndexOf(".") + 1
NS = NS.Substring(0, Index)
Dim ClassType As String = CType(BaseFlag, TestType).ToString()
Dim Test As BaseTest = Activator.CreateInstance(Type.GetType(NS & ClassType))
Test.Name = Name
Return Test
End Function
End Class
Public Class TestB
Inherits BaseTest
End Class
答案 0 :(得分:2)
第一步是弄清楚如何在类名称为字符串的情况下获得反射以创建对象实例。以下是一种方法的示例:
Dim o As Object = Activator.CreateInstance(Type.GetType("MyNameSpace.A"))
一旦你有了这个工作,你需要做的就是获取枚举值的字符串名称。要做到这一点,您需要做的就是在枚举对象上调用ToString
方法,例如,在您的情况下:
Dim className As String = CType(Val, GeneralClassType).ToString()
完成后,您可以简单地将类名连接到命名空间以创建对象:
Dim o As Object = Activator.CreateInstance(Type.GetType("MyNameSpace." & className))
您发布的示例是类型安全的,而使用反射,就像这样,不是。此外,反射可能会慢一点。您需要根据您的具体情况决定是否值得放弃该类型的安全性和效率。