Benutzer mit den meisten Antworten
Variable Typ Convertierung

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
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öglichkeitGruß Elmar
- Als Antwort markiert Palin Montag, 23. Januar 2012 20:24
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öglichkeitGruß Elmar
- Als Antwort markiert Palin Montag, 23. Januar 2012 20:24
-
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.
MFGBjörn
- Bearbeitet Palin 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.htmlsiehe 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
-
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
- Bearbeitet Ellen Ramcke Freitag, 20. Januar 2012 20:27
-
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.