Typen ermitteln und als neu deklarieren

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von Kangaroo.

    Typen ermitteln und als neu deklarieren

    Wunderschönen guten Abend Community.

    Ich habe ein kleines Problem und weiß nicht wie ich es lösen kann.
    Man darf den Titel nicht falsch verstehen, ich möchte keine Typen vergleichen.

    Mein Problem ist folgendes

    VB.NET-Quellcode

    1. Public Function CreateDokument_x2(ByVal Dokument As Form) As Form
    2. Dim Tdocument As Form
    3. Tdocument = New <Könnten verschiedene Formen sein(siehe Functions Parameter)>
    4. '...
    5. End Function


    Nun dachte ich daran ich könnte vielleicht ermitteln und neu deklarieren.
    Habe mich zu wenig mit dem Thema beschäftigt, obwohl es denke ich zu den einfachsten Grundlagen gehören sollte.

    Selbstverständlich würde mir wie immer ein Stichpunkt reichen, nachdem ich mich erkundigen kann.

    Danke Sehr! LG.L
    Ich bin möglicherweise falsch informiert, aber der Compiler muss wissen welcher Typ gemeint ist.
    Mal sehen...
    Mit generischen Typen funktioniert es nicht so einfach. ""New" kann nicht für einen Typparameter verwendet werden, der keine New-Einschränkung aufweist."

    Du könntest allerdings ein Enum verwenden und dieses der Funktion übergeben und anhand des Wertes andere Typen verwenden.
    So zum Beispiel:

    VB.NET-Quellcode

    1. Enum FormTyp As Integer
    2. Form = 0
    3. Form1 = 1
    4. Form2 = 2
    5. End Enum
    6. Function Foo(ByVal Typ As FormTyp) As Boolean
    7. Dim Test As Object
    8. Select Case Typ
    9. Case FormTyp.Form
    10. Test = New Form
    11. Case FormTyp.Form1
    12. Test = New Form1
    13. Case FormTyp.Form2
    14. Test = New Form2
    15. Case Else
    16. 'Keine Ahnung was
    17. End Select
    18. 'Hier weiter machen
    19. End Function


    @Vorposter:
    Ich weiß nicht wie man das gelöst kriegen könnte (siehe oben).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @Niko Ortner
    Genau so mache ich es derzeit auch, doch mir gefällt das nicht so gut.
    Das ist mir auf dauer zu umständlich da ich doch gerne meine Formen erkennen lassen möchte.

    Wenn sich doch noch eine Möglichkeit finden lasse wäre das super.
    (Habe vor demnächst auch aus Fremden Klassenbibliotheken die Formen anzunehmen, denke jedoch das ist dann doch zu umständlich)
    LG.L
    Hi
    Meinst du Reflection? Schau dir mal folgende Codes an:

    "einfache" Instanzierung mit parameterlosem Konstruktor:

    VB.NET-Quellcode

    1. Dim type As Type = GetType(Form1)
    2. Dim form As Form = DirectCast(Activator.CreateInstance(type), Form)


    VB.NET-Quellcode

    1. Dim type As Type = GetType(Form1)
    2. Dim ctr As Reflection.ConstructorInfo = type.GetConstructor(Reflection.BindingFlags.Public Or Reflection.BindingFlags.Instance, New Type(){...})
    3. Dim form As Form = DirectCast(ctr.Invoke(New Object(){...}), Form)

    New Type(){...} ersetzt du halt mit den Parameter-Typen des gewünschten Konstruktors, New Object(){...} mit den zugehörigen Werten.

    Da es keine abstrakten Konstruktoren gibt, ist halt die Funktionsfähigkeit von Activator.CreateInstance nicht gewährleistet. Was anderes ist es bei Wertetypen. Beachte aber, dass das setzen von Eigenschaften bei Wertetypen fehlschlägt. Bei Feldern müsste es auch fehlschlagen, das habe ich aber noch nicht überprüft. Also, es kommt kein Fehler, sondern es tut sich einfach nichts, da die Parameter nicht inout sind... Auf jeden Fall gibt es für jeden von VB unterstützten Member-Typen eine korrespondierende Klasse, die von Reflection.MemberInfo erbt. Schau dir dazu einfach mal alle Get*-Funktionen der Type-Klasse an. Die Type-Klasse erbt übrigens auch von Reflection.MemberInfo.

    Die Instanzen der Formen kriegst du übrigens unschönerweise mit

    VB.NET-Quellcode

    1. Dim form As Form = DirectCast(GetType(My.MyProject.MyForms).GetProperty(formType.Name, Reflection.BindingFlags.Public Or Reflection.BindingFlags.Instance).GetValue(My.Forms, New Object() {}), Form)

    Ich empfehle allerdings eine eigene Main-Prozedur. Das ist schön, einfach und elegant hand zu haben und nicht hässlich, blöd und sch...lecht. Was ist z.B. wenn man das abändert? Dann ist es einfach nicht mehr allgemeingültig... Also: Lieber eine Klasse erzeugen, die von System.Collections.ObjectModel.KeyedCollection(Of Type, Form) erbt und einfach den Typ der Form einreiht, dann hat man diesen ganzen Mist nicht... Das dynamische erzeugen der Forms-Instanzen, denen ich übrigens immer einen parameterlosen Konstruktor anhänge, weil man andere gar nicht braucht (wenn man meinen Stil verwendet), kann ebenfalls über Reflection geschehen.

    Gruß
    ~blaze~
    @blaze ziemlich heftig für diese Uhrzeit , aber interessanter Code

    Aber vielleicht reicht dem TE ja für den Anfang die von Dir genannte 'einfache Instanziierung' über Activator.CreateInstance aus

    Einfache Instanziierung mit parameterlosem Konstruktor

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    3. ' formX erzeugen
    4. Dim fx As Form = Activator.CreateInstance(GetType(Formx))
    5. fx.Show()
    6. ' formY erzeugen
    7. Dim fy As Form = Activator.CreateInstance(GetType(FormY))
    8. fy.Show()
    9. End Sub
    10. End Class
    11. Class Formx
    12. Inherits Form
    13. Public Sub New()
    14. Me.Text = "FORMX"
    15. End Sub
    16. End Class
    17. Class FormY
    18. Inherits Form
    19. Public Sub New()
    20. Me.Text = "FORMY"
    21. End Sub
    22. End Class


    Das geht natürlich auch bei Formen aus externen Assemblies, indem man diese per Assembly.LoadFile erst einmal lädt + per CreateInstance instanziert -> C# - Correct Way to Load Assembly

    @Lawliet wozu benötigst Du überhaupt diese Art des dynamischen Generierens von Formen aus dem Typ, wenn Du noch keine externen Libraries verwendest ?