Unterscheidung Generisches Objekt / Liste(Of )

  • VB.NET
  • .NET (FX) 4.0

Es gibt 23 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Unterscheidung Generisches Objekt / Liste(Of )

    Hallo Forum,

    ich komme mal wieder mit einer Frage an, bei der ich mir seit Wochen den Kopf zerbreche. ||

    Ich habe eine Funktion (bzw. zwei gleichnamige Funktionen), welche entweder eine generische Liste oder ein generisches Objekt als Parameter annimmt. (siehe Codebeispiel unten)

    VB.NET-Quellcode

    1. Public Function test1(Of T)(ByVal Obj As T)
    2. Tue etwas...
    3. End Function
    4. Public Function test1(Of T)(ByVal Lst As List(Of T))
    5. Tue etwas anderes...
    6. End Function


    Mein Problem ist jetzt, dass egal ob ich eine Klasse oder eine Liste in die Funktion übergebe, immer die erste Funktion, also die mit dem Objekt, genommen wird. ?(
    Ich möchte jetzt aber, dass die Liste auch in die dementsprechende Funktion übergeben wird. ^^

    Könnt ihr mir da helfen? :love:

    MFG Souli ^^
    @Souleater857 Probier mal, im Aufruf den Parameter explizit zur gewünschten Signatur zu casten:

    VB.NET-Quellcode

    1. test1(CType(obj, Lst As List(Of T)))

    Zunächst gibst Du aber den Funktionen noch einen Rückgabetyp:
    Option Strict On.
    =================
    Dies funktioniert:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. test1(Of Integer)(42)
    3. test1(Of Integer)(New List(Of Integer))
    4. Dim ll = New List(Of Integer)
    5. test1(Of Integer)(ll)
    6. End Sub
    7. Public Function test1(Of T)(ByVal Obj As T) As Integer
    8. MessageBox.Show("T")
    9. Return 0
    10. End Function
    11. Public Function test1(Of T)(ByVal Lst As List(Of T)) As Integer
    12. MessageBox.Show("List(Of T)")
    13. Return 0
    14. End Function

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Mono Ich rufe die Funktion zum Beispiel so auf:

    VB.NET-Quellcode

    1. Dim cls As Auto
    2. Dim lst as List(Of Auto)
    3. test1(cls)
    4. test2(lst)


    @RodFromGermany
    Jo, Option Strict ist an und Rückgabewerte hat meine Funktion im Programm auch. :) Sorry, das war ein schlechtes Beispiel. :whistling:
    Das mit dem Cast probiere ich mal und gebe dir dann eine Rückmeldung, ob es geklappt hat. :thumbup:

    MFG Souli

    RodFromGermany schrieb:

    @Souleater857

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. test1(Of Integer)(42)
    3. test1(Of Integer)(New List(Of Integer))
    4. Dim ll = New List(Of Integer)
    5. test1(Of Integer)(ll)
    6. End Sub
    7. Public Function test1(Of T)(ByVal Obj As T) As Integer
    8. MessageBox.Show("T")
    9. Return 0
    10. End Function
    11. Public Function test1(Of T)(ByVal Lst As List(Of T)) As Integer
    12. MessageBox.Show("List(Of T)")
    13. Return 0
    14. End Function



    Vereinfachung:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. test1(42)
    3. test1(New List(Of Integer))
    4. Dim ll = New List(Of Integer)
    5. test1(ll)
    6. End Sub
    7. Public Function test1(Of T)(ByVal Obj As T) As Integer
    8. MessageBox.Show("T")
    9. Return 0
    10. End Function
    11. Public Function test1(Of T)(ByVal Lst As List(Of T)) As Integer
    12. MessageBox.Show("List(Of T)")
    13. Return 0
    14. End Function
    funzt auch

    Souleater857 schrieb:

    Das mit dem Cast probiere ich mal
    k.A., was "mit dem Cast" gemeint ist - aber wenn du an diesem Problem iwas mit Casts anstellst, machste was falsch.

    ErfinderDesRades schrieb:

    Vereinfachung:
    Das funktioniert bei mir (außer 42) nur dann, wenn nur eine Funtion Test1 da ist. Bei zweien will er es genau haben.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ErfinderDesRades schrieb:

    Fehlermeldung
    Fehler 1 Fehler bei der Überladungsauflösung, da keine zugreifbare "test1" für diese Argumente am spezifischsten ist:
    "Public Function test1(Of Integer)(Lst As System.Collections.Generic.List(Of Integer)) As Integer": Nicht spezifisch genug.
    "Public Function test1(Of System.Collections.Generic.List(Of Integer))(Obj As System.Collections.Generic.List(Of Integer)) As Integer": Nicht spezifisch genug.
    mit dem VS 2010
    Muss das ganze später noch mal mit dem VS2013 testen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo an alle,
    danke für eure Hilfe! :)

    Ein kleiner Denkanstoß vom ErfinderDesRades hat mir die Lösung gezeigt. :D

    Ich hatte folgenden Code:

    VB.NET-Quellcode

    1. Public Function test1(Of T)(ByVal Obj As T)
    2. Tue etwas...
    3. End Function
    4. Public Function test1(Of T)(ByVal Lst As List(Of T), Optional ByVal clearList As Boolean = False)
    5. Tue etwas anderes...
    6. End Function


    Ich dachte die optionalen Parameter würden in diesem Fall keine Rolle spielen... Falsch gedacht :whistling:
    Meine Lösung ist jetzt einfach, dass ich den optionalen Parameter entferne und die Liste per Code leer mache, wenn benötigt.

    Mit freundlichen Grüßen
    Souli :)

    ErfinderDesRades schrieb:

    Fehlermeldung
    Merkwürden, im Studio 2013 läuft das, im Studio 2010 nicht.
    ==========
    @Souleater857 Mach doch einfach zwei Methodennamen draus. :D
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @SoulEater:
    1. Mach unbedingt ganz schnell Option Strict ON
      Hinweise dazu findtste hier - sogar Filmle gibts (aber schnell gucken ;) ) : Visual Studio - Empfohlene Einstellungen
    2. Klar kannste den Methoden verschiedene Namen geben, aber an deiner Stelle wäre mir am wichtigsten, die Sprache richtig zu verstehen.
      Das Sprachfeature, an dem du dran bist heisst "Überladung", und deine Erwartungen waren eiglich ganz richtig, und imo nun ist wichtig, zu verstehen, was genau schief gelaufen ist. Evtl. lags ja am Strict Off bei dir.
      Wie gesagt: Willst du Programmieren, musst du es lernen, und "Überladung" gehört dazu.
      Hier noch ein Ultra-Kurz-Abriss - Überladung wird da auch angerissen:Grundlagen: Fachbegriffe

    @RodFromGermany: Zwei Methoden wären suboptimal für mich :o ich hätte das schon gerne über eine :)

    @ErfinderDesRades:
    1. Option Strict ON war und ist immer an! ;) Wie schon gesagt ich habe das Beispiel nur ohne Rückgabetyp direkt hier im Forum geschrieben. :)
    2. Ich weiß was "Überladung" ist und ich kenne mich gut in der Sprache aus. :)
    Ich war nur der Meinung, dass das mit der Überladung so auch klappen müsste. -> Again what learned :P

    Trotzdem danke für eure Hilfe :)

    MFG Souli :3

    Souleater857 schrieb:

    Ich dachte die optionalen Parameter würden in diesem Fall keine Rolle spielen
    Das hätte ich eigentlich auch erwartet.

    Souleater857 schrieb:

    Meine Lösung ist jetzt einfach, dass ich den optionalen Parameter entferne
    Du könntest in dem Fall natürlich auch eine dritte Überladung erzeugen, die erst das Boolean auswertet und dann die zweite Überladung aufruft.
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --

    Souleater857 schrieb:

    Option Strict ON war und ist immer an!


    Das hier zumindest kompiliert nur unter Strict Off:

    Souleater857 schrieb:


    VB.NET-Quellcode

    1. Public Function test1(Of T)(ByVal Obj As T)
    2. Tue etwas...
    3. End Function
    4. Public Function test1(Of T)(ByVal Lst As List(Of T))
    5. Tue etwas anderes...
    6. End Function
    Weil die Functions haben keinen RückgabeTyp.

    Aber nun habich immerhin das Problem nachgestellt, und was ich dachte, funzt, funzt doch net:

    VB.NET-Quellcode

    1. Private Sub Button1_Clic2k(sender As Object, e As EventArgs) Handles Button1.Click
    2. test1(42)
    3. test1(New List(Of Integer))
    4. Dim ll = New List(Of Integer)
    5. test1(ll)
    6. End Sub
    7. Public Sub test1(Of T)(ByVal Obj As T)
    8. 'Tue etwas...
    9. End Sub
    10. Public Sub test1(Of T As IList)(ByVal Lst As List(Of T), Optional ByVal clearList As Boolean = False)
    11. 'Tue etwas anderes...
    12. End Sub
    Und das funzt nicht nur in vb2010 net, sondern auch in 2013 funztes anders als man denkt (tückischerweise ohne CompilerFehler) - aber das sagtest du ja schon im Eingangspost.
    Also Problem ist, dass die Signaturen der test1()-Überladungen nicht spezifisch genug sind, also ein Parameter vom Typ List(Of T) passt auf die 2. Signatur ebensogut wie auf die erste Signatur.

    Lösungen wurden schon genannt, eine weitere wäre, den optionalen Parameter verbindlich zu machen, weil so - optional - zählt er nicht als Unterscheidungs-Merkmal der Signaturen.

    Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von „ErfinderDesRades“ ()