P. Waksman
P. Waksman

Reputation: 1009

there is any way to instantiate a new class based on enum?

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

Answers (1)

Steven Doggart
Steven Doggart

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

Related Questions