none
Variable Typ Convertierung RRS feed

  • Frage

  • Hallo Zusammen,

     

    wir haben bei uns im Quellcode ein ParameterArray als Objekt.

    In disen Array können verschieden Typen  stehen (zB. boolen, string oder auch MyKlasse).

     

    Je nacht Type wird jetzt in einer Risigen selection, der Wert erst in seinen Typ Conventiert und dann Verarbeitet.

     

    Meine Idee war jetzt die Risige Selection durch einen Methoden aufruf zu ersetzen.

    In der Form:

    Sub Foo(ByVal Wert as boolean)
    Sub Foo(ByVal Wert as Objekt)
    

     

    Wenn ich die Funktion im Code zB mit Foo(true) aufrufe. Wird auch die Passende Funkton genommen, nicht für Objekt.

    Das der Aufruf Foo(par(1)) nicht direkt klappt hab ich mir auch schon gedacht.

     

    Ich hatte aber Angenomen, das es eine Möglichkeit der Dynamischen Typ Convertierung gibt.

    So ähnlich wie.

    Dim Wert = DirectCast(par(1), TypeOf(par(1))

    Foo(Wert)

    Das Klappt leider nicht.

     

    Hat hier vileicht jemand eine Idee wie man, das möglicht ohne Select Case oder if Abfrage lösen kann.

     

    MFG

    Björn

     

     

     

     

     

     

     

     

     

     

     

     

    Freitag, 20. Januar 2012 16:53

Antworten

  • Hallo Björn,

    so ganz werden ich aus Deiner Beschreibung nicht schlau.

    Visual Basic behandelt System.Object etwas anders als andere Sprachen (C#),
    was aus der Philosophie der späten Bindung resultiert, siehe dazu
    Bestimmen des Objekttyps (Visual Basic)
    (dort insbesondere das Beispiel für CheckType).

    In einen expliziten Typ konvertieren kannst Du mit DirectCast, wobei Du den Typ direkt angeben musst,
    also z. B. DirectCast(variable, Klasse - etwas wie TypeOf(variable) geht nicht.
    Ab Visual Basic 2008 gibt es zudem TryCast, was im Gegensatz zu DirectCast keine Ausnahme wirft,
    wenn die Konvertierung fehlschlägt, sondern Nothing zurückgibt.
    Beide Methoden erfordern, dass der Zieltyp (Klasse oder Schnittstelle) enthalten ist.
    Mit CType wiederum können weitere Konvertierungen wie z. B. Integer auf Double vorgenommen werden,
    vorausgesetzt es existiert eine Konvertierungsmöglichkeit

    Gruß Elmar

    • Als Antwort markiert Palin Montag, 23. Januar 2012 20:24
    Freitag, 20. Januar 2012 17:18
    Beantworter

Alle Antworten

  • Hallo Björn,

    so ganz werden ich aus Deiner Beschreibung nicht schlau.

    Visual Basic behandelt System.Object etwas anders als andere Sprachen (C#),
    was aus der Philosophie der späten Bindung resultiert, siehe dazu
    Bestimmen des Objekttyps (Visual Basic)
    (dort insbesondere das Beispiel für CheckType).

    In einen expliziten Typ konvertieren kannst Du mit DirectCast, wobei Du den Typ direkt angeben musst,
    also z. B. DirectCast(variable, Klasse - etwas wie TypeOf(variable) geht nicht.
    Ab Visual Basic 2008 gibt es zudem TryCast, was im Gegensatz zu DirectCast keine Ausnahme wirft,
    wenn die Konvertierung fehlschlägt, sondern Nothing zurückgibt.
    Beide Methoden erfordern, dass der Zieltyp (Klasse oder Schnittstelle) enthalten ist.
    Mit CType wiederum können weitere Konvertierungen wie z. B. Integer auf Double vorgenommen werden,
    vorausgesetzt es existiert eine Konvertierungsmöglichkeit

    Gruß Elmar

    • Als Antwort markiert Palin Montag, 23. Januar 2012 20:24
    Freitag, 20. Januar 2012 17:18
    Beantworter
  • Hallo Elmar,

    erstmal danke für die hilfe.

     

    Nur wir haben sowas hier im Quellcode.

     

      For intI As Integer = 0 To par.Length
    
                If TypeOf par(intI) Is String Then
                    Dim Wert As String = CStr(par(intI))
                    Foo(Wert)
                ElseIf TypeOf par(intI) Is Integer Then
                    Dim Wert As Integer = CInt(par(intI))
                    Foo(Wert)
                ElseIf TypeOf (par(intI)) Is Button Then
                    Dim Wert As String = DirectCast(par(intI), Button)
                    Foo(Wert)
                ElseIf TypeOf par(intI) Is Boolean Then
                    Dim Wert As Boolean = CBool(par(intI))
                    Foo(Wert)
                ElseIf 
                    'usw.
                End If
    
       Next
    

    Ich such jetzt eine Möglichkeit, die ganzen ElseIf Anweisungen weg zu bekommen.

     


    MFG

    Björn

    • Bearbeitet Palin Freitag, 20. Januar 2012 17:50
    Freitag, 20. Januar 2012 17:50
  • Hallo Björn,

    unter Umständen! könnte man etwas über Expression machen, wie z. B. Marc Gravell "gezaubert" hat:
    http://www.yoda.arachsys.com/csharp/miscutil/usage/genericoperators.html

    siehe auch: http://stackoverflow.com/questions/793571/why-would-you-use-expressionfunct-rather-than-funct

    Ob das hier Sinn gibt bin, ich mir aber nicht sicher, vor allem wegen der sehr breit gestreuten Typen -
    von Basistypen bis zum Button ist doch ein weiter Weg.
    Und ein Dutzend (oder mehr) Überladungen von Foo würden das Problem nur an eine andere Stelle verlagern.

    Welche Aufgabe wird denn von der Methode bzw. dem Abschnitt / Klasse übernommen?

    Gruß Elmar

    Freitag, 20. Januar 2012 19:10
    Beantworter
  • Hallo Björn,

    ich kann den Sinn Deiner Frage auch nicht  nachvollziehen. Du hast ein Array von Objekten. OK das ist IO. In diesen Zeilen führst Du ein Cast von Button auf string aus:

              ElseIf TypeOf (par(intI)) Is Button Then
                    Dim Wert As String = DirectCast(par(intI), Button)
                    Foo(Wert)

    Was erwartest Du denn, was in "Wert" drin stehen soll?

    Hast Du übrigens Option strict ON gesetzt? Oder ich verstehe hier etwas nicht

    schöne Grüsse Ellen

    Nachtrag

    zu Deiner Anforderung. Im Prinzip gut. Aber was soll das bringen? Ich hatte eine ähnliche Aufgabe. Bei Daten, die aus einer Datenbank kommen, weis ich nicht immer welcher Typ das ist. Ich muss das vorher überprüfen um InvalidCastOperation abzufangen. Ein Beispiel sieht so aus. Vielleicht hilft Dir das:

     

       ''' <summary>
        ''' überprüft Null, Empty oder nothing
        ''' </summary>
        ''' <param name="item"></param>
        ''' <returns>True,False</returns>
        ''' <remarks>Überprüfung Datenbank items und string</remarks>
        <Extension()> Friend Function IsNotNothingOrEmptyOrDbNull(ByVal item As Object) As Boolean
            If TypeOf item Is System.DBNull Then Return False
            If TypeOf item Is String Then
                If CType(item, String) = String.Empty Then Return False
                If CType(item, String) = Nothing Then Return False
            End If
            Return True
        End Function


    Ich benutze/ I'm using VB2008 & VB2010

    Freitag, 20. Januar 2012 19:56
  • Hallo ihr beiden,

    @Elma
    mit einem Generischen Aufruf hatte ich es auch schon Probiert und Lamda Ausdrücke kann ich leider nicht Verwenden da ich leider nicht verwenden. Da ich auf das Framework 2.0 beschränkt bin.
    @Ellen
    Ich hab hier das umgekehrte Problem, bei mir geht es darum Parameter zu setzen um dann auf die Datenbank (Intersystems Caché) zu zugreifen.

    Der Datenbankanbieter stellt uns hier Klassen zur Datenbankanbindung bereit auch eine Klasse für die Parameter.
    Jetzt sind die Entwickler bei uns hingegangen und haben die Klasse hinter einer Eigenen Klasse gekapselt, was meines Erachtens gut so ist.
    Und wenn sie bei den Parametern nur Standarddatentypen fände ich es nicht so schlimm,
    leider sind die Leute hin gegangen und haben eigene Klassen für die Parameter erstell.
    Wie z.B. KundenParameter, KudenAdressenParameter usw.
    Was zu einen riesigen If-Block geführt hat, was nicht wirklich schön ist.
     (Wo bei mir Foo Aufgerufen wird, steht momentan noch der Code zur  Umwandlung und den Button hatte ich nur als Beispiel eingefügt um zu zeigen dass es sich hier auch im Komplexere Objekte handeln kann.)

    Da es leider nicht so Funktioniert wie ich Erhofft habe werde ich wohl eine Ebene höher ansetzen und schauen das ich in den Eigenen Klassen ein Interface implementiere. Ist ja auch den bessere Variante ich hatte aber gehofft, dass ich nicht die ganzen Klassen anpacken muss.

    p.s.
    @Ellen
    Wenn du deine Methode mit Nothing aufrufst wird sie True zuückgeben.
    Montag, 23. Januar 2012 09:59