【发布时间】:2014-06-10 15:42:16
【问题描述】:
有什么方法可以通过反射实例化一个基于枚举的新类?
基本上我想删除 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 函数基于从数据库获取的类型和参数构建类。 但我需要有案例来创建一个类型的新实例。
我知道我可以通过反射来实例化一个类,但前提是你知道最终类型。 没有办法做到这一点,比如将类名保存在数据库中?
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 函数中使用此实例。但在这里我需要知道类型 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
【问题讨论】:
-
进行反射以节省打字可能并不总是正确的决定。如果你有很多重复的代码,你应该重新考虑你的设计。反思似乎更容易。从长远来看,您希望有很多维护噩梦。当然,除非你证明了这一举动是合理的。
-
我正在使用反射,因为我不知道另一种方法可以做到这一点。关键是,很快我将在我的基地中为所有标志提供大量枚举。此标志确定一种或另一种流动方式。所以为了避免很多类有相同的代码,a做了一些泛型类,具体的类针对具体的方式,减少了很多类的数量和维护。旧代码充满了“Dim ob as New EspecificClass”,没有超类,而不是调用一些不特定的方法。好吧,现在我只需要担心构建器而不是所有“Dim ob as New EspecificClass” .
-
您似乎正在分支工作流程,即有一组恒定(或有限,更好地说)步骤,而它们之间的链接是动态的。您是否考虑过表格驱动设计?
-
以前从不使用“表驱动设计”,但我会检查一下。谢谢。
-
您可能会发现这些链接很有用:codeproject.com/Articles/42732/Table-driven-Approach 和 en.wikipedia.org/wiki/Control_table,让您了解术语(以及进一步搜索的想法)。
标签: vb.net reflection enums instantiation