Wie lautet das VarType-Äquivalent in VB.NET

  • VB.NET

Es gibt 29 Antworten in diesem Thema. Der letzte Beitrag () ist von Niko Ortner.

    Wie lautet das VarType-Äquivalent in VB.NET

    Hallo,
    kann mir jemand posten, wie die Entsprechung von Microsofts.VisualBasic.VarType(Value)
    in VB2008 heißt? Bei den Microsofts.VisualBasic.VarTypen werden ja die "UTypen" nicht
    erkannt bzw. unterstützt; oder gibt es das in VB.NET (was ich mir allerdings überhaupt
    nicht vorstellen kann) nicht mehr?
    mfG DHB

    Ich meine:
    :P Es sollten nur ernstzunehmende Beiträge eingestellt werden!
    :( Beiträge, die nur deren Anzahl in die Höhe treiben sollen, stehlen Lesern deren Zeit und schenken nur Frust.
    ;) Wenn ein Autor sein Thema für erledigt hält, sollte er dies kurz als letzten Eintrag vermerken.
    8) Leser wüssten dann, dass hier weitere Beiträge nicht mehr sinnvoll sind.
    Hey Kevin,
    also damit komme ich nicht weiter!
    Weder mit GetType(Value) noch mit Value.GetType()!

    Worauf soll ich dann testen?
    If Value.GetType = ??? then ...

    Unter VB6 war es doch so, dass man
    If VarType(Value) = VariantType.Byte then ...
    schreiben konnte; dazu brauche ich die Entsprechung!
    mfG DHB

    Ich meine:
    :P Es sollten nur ernstzunehmende Beiträge eingestellt werden!
    :( Beiträge, die nur deren Anzahl in die Höhe treiben sollen, stehlen Lesern deren Zeit und schenken nur Frust.
    ;) Wenn ein Autor sein Thema für erledigt hält, sollte er dies kurz als letzten Eintrag vermerken.
    8) Leser wüssten dann, dass hier weitere Beiträge nicht mehr sinnvoll sind.
    Beim Typ-Test wär's so:

    VB.NET-Quellcode

    1. Dim value As Object = CByte(255)
    2. If TypeOf value Is Byte Then
    3. MessageBox.Show("yo")
    4. End If

    Da wird aber die komplette Vererbungskette durchgegangen, also z.B. TypeOf Form Is Control würde True zurückgeben, da Form von Control erbt. Sonst wär's möglich, das per If value.GetType() Is GetType(Byte) zu machen.
    Es gibt übrigens eine Enumeration mit ein paar Standardtypen, TypeCode. Die Kannst du per Convert behandeln (ist aber eher nicht so praktisch).

    Gruß
    ~blaze~
    @Artentus & @~blaze~, Danke zunächst - damit kann ich schon mal gut arbeiten!

    Besser wäre es allerdings für mich, wenn man die Abfrage auch über Select Case
    vornehmen könnte; wenn einer dazu noch etwas weiß, das wäre schon gut! So wie:

    VB.NET-Quellcode

    1. Select Case TypeOf Value ' <- Is erwartet ??
    2. Case Is GetType(SByte) : BitCtEnd = 7 ' <- Relationaler Operator erwartet?
    3. End Select
    4. ' hiermit hätt`s keine Probleme:
    5. Select Case VarType(Value)
    6. Case VariantType.Byte : BitCtEnd = 7
    7. End Select

    Habe schon etliche Kombinationen sowohl mit TypeOf als auch mit GetType()
    ausprobiert, aber ich komme da auf keinen grünen Zweig ?(
    Tscha, das sind eben typische UMsteigerprobleme!
    mfG DHB

    Ich meine:
    :P Es sollten nur ernstzunehmende Beiträge eingestellt werden!
    :( Beiträge, die nur deren Anzahl in die Höhe treiben sollen, stehlen Lesern deren Zeit und schenken nur Frust.
    ;) Wenn ein Autor sein Thema für erledigt hält, sollte er dies kurz als letzten Eintrag vermerken.
    8) Leser wüssten dann, dass hier weitere Beiträge nicht mehr sinnvoll sind.
    Ggf. wär's dann sinnvoll, in einen umfassenderen Typen zu casten.
    Ansonsten funktioniert anscheinend das:

    VB.NET-Quellcode

    1. Select Case 123.GetType()
    2. Case GetType(Integer)
    3. Case GetType(Byte)
    4. End Select

    Was soll BitCtEnd darstellen? 7 sieht so aus, als wäre das quasi das "höchstwertige Bit" für positive Zahlen.

    Gruß
    ~blaze~
    Ich kenne noch von früheren Zeiten einen VARIANT-Typ (OleVariant), in den sich alles aber auch alles reinpacken ließ, sogar ganze Bilder.
    War einmal gut zur Kommunikation mit Access-Datenbanken und zum Transport von Bildern über DCom zu anderen PCs.
    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!
    @~blaze~
    Es ist mir ja schon fast peinlich, aber so geht´s auch nicht!

    VB.NET-Quellcode

    1. Select Case Value.GetType() ' oder auch 123.GetType() (keine Fehlermeldung!)
    2. Case Is GetType(Int32) ' Fehler: Relationaler Operator erwartet!
    3. Case Is= GetType(Byte) ' Fehler: Der =-Operator ist für die Typen "System.Type" und "System.Type" nicht definiert
    4. Case GetType(UShort) ' Fehler: Der =-Operator ist für die Typen "System.Type" und "System.Type" nicht definiert
    5. End Select
    mfG DHB

    Ich meine:
    :P Es sollten nur ernstzunehmende Beiträge eingestellt werden!
    :( Beiträge, die nur deren Anzahl in die Höhe treiben sollen, stehlen Lesern deren Zeit und schenken nur Frust.
    ;) Wenn ein Autor sein Thema für erledigt hält, sollte er dies kurz als letzten Eintrag vermerken.
    8) Leser wüssten dann, dass hier weitere Beiträge nicht mehr sinnvoll sind.
    @DHB: Setz einen Haltepunkt drauf und sieh Dir an, was drin steht.
    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!
    Der Operator ist erst ab einem Framework definiert. Ich hab's mit 4.0 ausprobiert, da tuts, aber beim 2.0er war der glaub ich nicht definiert.
    Wofür genau brauchst den jetzt? Häufig gibt's ne elegantere Lösung, wie z.B. über den TypeCode (funktioniert aber nur mit ausgewählten Typen).
    Ansonsten geht halt noch eine manuelle Überprüfung aller Typen per If oder über ein Dictionary(Of Type, Action(Of Object)) oder so. Aber sag' erst mal, was genau du machen willst.

    Gruß
    ~blaze~
    TypeOf <Expression> Is <TypeName> ist ein fester Bestandteil der CLR. TypeOf <Expression> ist kein separater Teil, sondern gehört fix in dieses Konstrukt hinein. Deshalb kann man es nicht in der Select Case -Verzweigung verwenden.

    System.Type ist ein Referenztyp, deshalb kann der =-Oparator (Istgleich) nicht darauf angewendet werden.
    Select Case verwendet aber genau diesen Oparator.

    Eine Möglichkeit wäre hier das:

    VB.NET-Quellcode

    1. Select Case True
    2. Case TypeOf <Expression> Is <TypeName>
    3. Case TypeOf <Expression> Is <TypeName>
    4. Case ...
    5. End Select


    Edit: ~blaze~ hat recht. Ab einem gewissen Framework gibt's den =-Oparator für System.Type. Dabei handelt es sich aber um einen Aufruf an die CLR, deshalb muss man testen, was der macht (Hab ich: Macht komplett das Selbe wie ein Referenzvergleich mit dem Is-Oparator).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils
    @~blaze~
    Ich weiß nicht, ob es Dich wirklich so genau interessiert, aber da Du Dich bisher so unglaublich in mein Problem rein gehängt hast, will ich Dir Deine Frage gern beantworten:
    Also - ich bin im Moment dabei ein Extensions-Modul unter dem Haupt-Namespace meiner Library in einer eigenen Assemblie zu programmieren. In diesem speziellen Fall sollen alle "Int-Werte" zusätzlich die Extensions-Funktion ".ToBinary" erhalten und jede von Ihnen soll noch 3x überladen sein; d.h.: es wären 3 (Überladungen) x 4 (Byte,Int16, Int32, Int64) x 2 (Mit und ohne Vorzeichen) = 24 Funktionen insgesamt und das immer mit etwa dem gleichen Code. Um dies (-en Code) zu reduzieren, ist es die Aufgabe, im Extensions-Modul selbst den übergebenen VariablenTyp und damit die Iterationsweite für die entsprechende Variable zu ermittel. Dadurch kann das Iterieren (und anderes) dann zentral ausgeführt werden.
    Diesen Vorgang der Bestimmung der aktuellen Iterationsgrenze brauche ich quasi immer, wenn ich eine Extensions-Funktion für alle Int-Werte erstelle.
    Ich werde es jetzt so machen, wie Du es ursprünglich vorgeschlagen hast; wäre zwar mit Select Case eleganter gewesen, aber so geht´s ja auch. Übrigens mit Deiner Vermutung hast Du schon ganz recht gehabt - BitCtEnd stellt die jeweilige Bitgrenze dar, wobei das letzte Bit in den meisten Fällen gesondert behandelt wird; aber das würde jetzt zu weit führen.

    VB.NET-Quellcode

    1. If TypeOf Value Is Byte OrElse TypeOf Value Is SByte Then BitCtEnd = 7
    2. If TypeOf Value Is Int16 OrElse TypeOf Value Is UInt16 Then BitCtEnd = 15
    3. If TypeOf Value Is Int32 OrElse TypeOf Value Is UInt32 Then BitCtEnd = 31
    4. If TypeOf Value Is Int64 OrElse TypeOf Value Is UInt64 Then BitCtEnd = 63

    Ich hoffe, dass ich mich klar genug ausgedrückt habe.

    Nochmals herzlichen Dank für Dein Interesse und Deine Mühe mir geholfen zu haben.
    mfG DHB

    Ich meine:
    :P Es sollten nur ernstzunehmende Beiträge eingestellt werden!
    :( Beiträge, die nur deren Anzahl in die Höhe treiben sollen, stehlen Lesern deren Zeit und schenken nur Frust.
    ;) Wenn ein Autor sein Thema für erledigt hält, sollte er dies kurz als letzten Eintrag vermerken.
    8) Leser wüssten dann, dass hier weitere Beiträge nicht mehr sinnvoll sind.
    @~blaze~:
    Jau, das funktioniert aber nicht mit bereits existierenden Typen, weil der Oparator in der Klasse definiert sein muss, für die er definiert ist:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Public Shared Operator =(ByVal Item1 As Type, ByVal Item2 As Type) As Boolean
    3. End Operator
    4. Public Shared Operator <>(ByVal Item1 As Type, ByVal Item2 As Type) As Boolean
    5. End Operator
    6. End Class

    Mindestens ein Parameter dieses binären Operators muss den enthaltenden Typ "WindowsApplication1.Form1" aufweisen.


    Edit: @DHB:
    Das funktioniert so nicht, weil Integer (und byte und UInt16 usw...) ineinander konvertierbare Wertetypen sind.

    VB.NET-Quellcode

    1. Sub Foo()
    2. Dim Temp As Byte = 124
    3. Bar(Temp)
    4. End Sub
    5. Sub Bar(Value As Integer)
    6. '...
    7. End Sub

    Hier wird das Byte zu einem Integer konvertiert.
    Fragt man also in der Bar-Sub folgendes ab:

    VB.NET-Quellcode

    1. If TypeOf Value Is Byte

    Dann wird immer False herauskommen... theoretisch zumindest, denn der TypeOf-Is-Oparator funktioniert (logischerweise) nur mit Referenztypen.

    Da wird Dir nichts anderes übrigbleiben, als mehrere Überladungen zu programmieren. (Oder Du deklarierst den ersten Parameter als Object, wodurch das Byte beim Aufruf "geboxt" wird und dann funktioniert der TypeOf-Is-Oparator wieder. Das würde aber den Sinn der Erweiterungsmethode einschränken, weil sie auf alle Werte angewendet werden kann.
    Aber so viel Aufwand ist das Schreiben dieser Methoden garnicht:

    VB.NET-Quellcode

    1. <Extension> _
    2. Public Overloads Function ToBinary(Target As Byte) As String
    3. Return Convert.ToString(Target, 2).PadLeft(8)
    4. End Function
    5. <Extension> _
    6. Public Overloads Function ToBinary(Target As UInt16) As String
    7. Return Convert.ToString(Target, 2).PadLeft(16)
    8. End Function
    9. '...
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Niko Ortner“ ()

    Alle primitiven Datentypen implementieren IConvertible. Wenn du die Extension auf IConvertible definierst, kannst du das ggf. schöner lösen.

    VB.NET-Quellcode

    1. Public Module BinaryExtensions
    2. <Runtime.CompilerServices.Extension()>
    3. Public Function ToBinary(ByVal value As IConvertible) As Byte()
    4. Select Case value.GetTypeCode()
    5. Case TypeCode.SByte
    6. Case TypeCode.UInt64
    7. '...
    8. End Select
    9. End Function
    10. End Module

    TypeCode ist so definiert:

    VB.NET-Quellcode

    1. Public Enum TypeCode
    2. Empty = 0
    3. Object = 1
    4. DBNull = 2
    5. Boolean = 3
    6. Char = 4
    7. SByte = 5
    8. Byte = 6
    9. Int16 = 7
    10. UInt16 = 8
    11. Int32 = 9
    12. UInt32 = 10
    13. Int64 = 11
    14. UInt64 = 12
    15. Single = 13
    16. Double = 14
    17. Decimal = 15
    18. DateTime = 16
    19. String = 18
    20. End Enum

    Übrigens, da TypeCode bis auf die 17 immer fortlaufend numeriert ist, könnte man das als Index in einem Delegaten-Array verwenden. Der Vorgang wäre dann in O(1).
    Bei IConvertible musst du aber auch die Typen, die keine primitiven Datentypen sind, betrachten.

    So viel Arbeit ist das btw. nicht und ich helf' ja gern. ;)

    Gruß
    ~blaze~
    @~blaze~: Soweit kann ich Dir folgen, aber wie konvertiere ich einen IConvertible-Wert zu einen String im binären Format?
    Ich habe hier was gefunden: calebmcelrath.wordpress.com/tag/iconvertible/ Aber hier wird auch nur zuerst zu Int64 konvertiert, und dann zu String. Die Methode gefällt mir nicht so gut, weil das bei UInt64-Werten größer als Int64.MaxValue zu Problemen führt (auch wenn man's selten verwendet).
    "Luckily luh... luckily it wasn't poi-"
    -- Brady in Wonderland, 23. Februar 2015, 1:56
    Desktop Pinner | ApplicationSettings | OnUtils