Reputation: 1009
there is any way to instantiate a new class based on enum through reflection?
Basicly i wanna to remove the Select Case. I have alot of Enum and builders....
For example:
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
The Function BuildClass build a class base on a type and parameters get from Database. But i need to have the Case to create a new instance of a type.
I know i can instantiate a class through reflection, but only if you know the final type. There is no way to do this dinamicy, like save the class name on database?
public function InstantiateClass(of T)() as T
Dim NewObject as GeneralClass = GetType(T).GetConstructor(New Type() {}).Invoke(New Object() {})
return NewObject
end class
than i can get something like
Dim Var1 as GeneralClass = InstantiateClass(of A)()
and use this instance inside the Build function. But here i need to know the Type A
BaseTest example, working with enum name.
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
Upvotes: 2
Views: 1280
Reputation: 43743
The first step is to figure out how to get reflection to create an object instance given the class name as a string. Here's an example of one way to do that:
Dim o As Object = Activator.CreateInstance(Type.GetType("MyNameSpace.A"))
Once you have that working, all you need to do is to get the string name of the enumeration value. To do that, all you need to do is to call the ToString
method on the enumeration object, for instance, in your case:
Dim className As String = CType(Val, GeneralClassType).ToString()
Once you have that, you can simply concatenate the class name to the namespace to create the object:
Dim o As Object = Activator.CreateInstance(Type.GetType("MyNameSpace." & className))
The example you posted is type-safe, whereas using reflection, like this, is not. Also, reflection can be a bit slower. You need to decide, based on your particular situation, whether or not it is worth giving up that type-safety and efficiency.
Upvotes: 2