Stringausdrücke auf Umwandlung in verschiedene Datentypen überprüfen

  • VB.NET

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von VB1963.

    Stringausdrücke auf Umwandlung in verschiedene Datentypen überprüfen

    Hi Community!

    Wie könnte man den Code noch optimieren?

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Private Function parseValue(obj As Object, v As String) As Boolean
    2. Dim T = GetType(obj)
    3. Select Case True
    4. Case T Is GetType(Boolean) : Dim bol As Boolean : If Boolean.TryParse(v, bol) Then Return True
    5. Case T Is GetType(DateTime) : Dim dtm As Date : If Date.TryParse(v, dtm) Then Return True
    6. Case T Is GetType(Decimal) : Dim dec As Decimal : If Decimal.TryParse(v, dec) Then Return True
    7. Case T Is GetType(Double) : Dim dbl As Double : If Double.TryParse(v, dbl) Then Return True
    8. Case T Is GetType(Int16) : Dim i16 As Int16 : If Int16.TryParse(v, i16) Then Return True
    9. Case T Is GetType(Int32) : Dim i32 As Int32 : If Int32.TryParse(v, i32) Then Return True
    10. Case T Is GetType(Int64) : Dim i64 As Int64 : If Int64.TryParse(v, i64) Then Return True
    11. Case T Is GetType(Single) : Dim sng As Single : If Single.TryParse(v, sng) Then Return True
    12. Case T Is GetType(UInt16) : Dim u16 As UInt16 : If UInt16.TryParse(v, u16) Then Return True
    13. Case T Is GetType(UInt32) : Dim u32 As UInt32 : If UInt32.TryParse(v, u32) Then Return True
    14. Case T Is GetType(UInt64) : Dim u64 As UInt64 : If UInt64.TryParse(v, u64) Then Return True
    15. End Select
    16. Return False
    17. End Function
    Was soll das überhaupt, dass Du die überladenen Funktionen der einzelnen Typen wieder durch einen Flaschenhals zwängst?
    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 Flaschenhals zeigt sich, wenn ich zum Beispiel den Werttyp einer DGV-Spalte zuerst feststellen muss,
    und wissen will, ob ein String auf diesen Werttyp umgewandelt werden kann.
    Vermutlich gehe ich es falsch an?
    Mir gefallen diese Zeilen auch nicht...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB1963“ ()

    Weise dem DGV ein typisiertes DataSet als DataBinding zu, da weiß die Spalte, ob sie Integer oder DateTime ist und fertich.
    Da hat der @ErfinderDesRades: einige fundierte Beiträge gepostet.
    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!
    Ja, das ist richtig - da hab ich schon viel nachgeschaut :)

    es liegt an meinen kargen Angaben ... :!:

    Ich befasse mich zur Zeit mit meiner selbstgebauten DataGridViewColumn-Classe,
    wo ich bei den einzelnen Spalten auch die Auswaldaten via Items-Auflistung einer Combobox übergeben kann.
    In dieser Auflistung können natürlich Angaben drinnen stehen, die nicht zur ausgewählten Spalte passen.
    Diese Einträge möchte ich bei der Initialisierung der ComboBox-Auswahlliste übergehen, dass sie gar nicht zur Auswahl stehen.
    Ich bin da noch nicht auf eine gescheite Lösung gekommen.

    Ich hoffe, es war verständlich.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VB1963“ ()

    VB.NET-Quellcode

    1. Private Function CanParse(ByVal obj As Object, ByVal v As String) As Boolean
    2. Return Boolean.TryParse(v, New Boolean) OrElse Date.TryParse(v, New Date) OrElse Decimal.TryParse(v, New Decimal) '...
    3. End Function

    vlt kann man auch was einfacheres mit TypConvertern frickeln

    VB.NET-Quellcode

    1. Private Function CanConvert(ByVal obj As Object, ByVal v As String) As Boolean
    2. return TypeDescriptor.GetConverter(obj.Gettype).CanConvertFrom(gettype(string))
    3. End Function
    (so ähnlich)

    Aber alles ziemlich unschön, aber da ich das konkrete Prob nicht wirklich kenne, weißich auch nix besseres :(
    Hi
    habe mal was zusammengeschrieben. Wenn es "allgemeingültig" sein soll, würde ich das so machen:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Shared Sub Test()
    2. Dim p As Object = Nothing
    3. If Parse(Of String)("bla", p) Then
    4. MessageBox.Show(p.ToString() + vbCrLf + p.GetType().ToString())
    5. End If
    6. If Parse(Of Integer)("123", p) Then
    7. MessageBox.Show(p.ToString() + vbCrLf + p.GetType().ToString())
    8. End If
    9. If Parse(Of Char)("a", p) Then
    10. MessageBox.Show(p.ToString() + vbCrLf + p.GetType().ToString())
    11. End If
    12. If Parse(Of Color)("123; 15; 2", p) Then
    13. MessageBox.Show(p.ToString() + vbCrLf + p.GetType().ToString())
    14. End If
    15. End Sub
    16. Private Delegate Function Parser(ByVal input As String, ByRef returnValue As Object) As Boolean
    17. Public Shared Function Parse(Of T)(ByVal input As String, ByRef returnValue As Object) As Boolean
    18. If GetType(T).GetInterface(GetType(IConvertible).FullName) IsNot Nothing Then
    19. Return Parse(input, Type.GetTypeCode(GetType(T)), returnValue)
    20. Else
    21. Dim tca() As System.ComponentModel.TypeConverterAttribute = DirectCast(GetType(T).GetCustomAttributes(GetType(System.ComponentModel.TypeConverterAttribute), False), System.ComponentModel.TypeConverterAttribute())
    22. Dim tc As System.ComponentModel.TypeConverter
    23. For Each tcainst As System.ComponentModel.TypeConverterAttribute In tca
    24. Try
    25. tc = DirectCast(Activator.CreateInstance(Type.GetType(tcainst.ConverterTypeName)), System.ComponentModel.TypeConverter)
    26. If tc.CanConvertFrom(GetType(String)) Then
    27. returnValue = tc.ConvertFromString(input)
    28. Return True
    29. End If
    30. Catch
    31. 'geht halt nicht
    32. End Try
    33. Next
    34. Return False
    35. End If
    36. End Function
    37. Public Shared Function Parse(ByVal input As String, ByVal typeCode As TypeCode, ByRef returnValue As Object) As Boolean
    38. Static dgl() As Parser = New Parser() {Nothing,
    39. Nothing,
    40. Function(inp As String, ByRef value As Object)
    41. Dim b As Boolean
    42. If Boolean.TryParse(inp, b) Then
    43. value = b
    44. Return True
    45. Else
    46. Return False
    47. End If
    48. End Function,
    49. Function(inp As String, ByRef value As Object)
    50. Dim b As Boolean
    51. If Boolean.TryParse(inp, b) Then
    52. value = b
    53. Return True
    54. Else
    55. Return False
    56. End If
    57. End Function,
    58. Function(inp As String, ByRef value As Object)
    59. Dim b As Char
    60. If Char.TryParse(inp, b) Then
    61. value = b
    62. Return True
    63. Else
    64. Return False
    65. End If
    66. End Function,
    67. Function(inp As String, ByRef value As Object)
    68. Dim b As SByte
    69. If SByte.TryParse(inp, b) Then
    70. value = b
    71. Return True
    72. Else
    73. Return False
    74. End If
    75. End Function,
    76. Function(inp As String, ByRef value As Object)
    77. Dim b As Byte
    78. If Byte.TryParse(inp, b) Then
    79. value = b
    80. Return True
    81. Else
    82. Return False
    83. End If
    84. End Function,
    85. Function(inp As String, ByRef value As Object)
    86. Dim b As Short
    87. If Short.TryParse(inp, b) Then
    88. value = b
    89. Return True
    90. Else
    91. Return False
    92. End If
    93. End Function,
    94. Function(inp As String, ByRef value As Object)
    95. Dim b As UShort
    96. If UShort.TryParse(inp, b) Then
    97. value = b
    98. Return True
    99. Else
    100. Return False
    101. End If
    102. End Function,
    103. Function(inp As String, ByRef value As Object)
    104. Dim b As Integer
    105. If Integer.TryParse(inp, b) Then
    106. value = b
    107. Return True
    108. Else
    109. Return False
    110. End If
    111. End Function,
    112. Function(inp As String, ByRef value As Object)
    113. Dim b As UInteger
    114. If UInteger.TryParse(inp, b) Then
    115. value = b
    116. Return True
    117. Else
    118. Return False
    119. End If
    120. End Function,
    121. Function(inp As String, ByRef value As Object)
    122. Dim b As Long
    123. If Long.TryParse(inp, b) Then
    124. value = b
    125. Return True
    126. Else
    127. Return False
    128. End If
    129. End Function,
    130. Function(inp As String, ByRef value As Object)
    131. Dim b As ULong
    132. If ULong.TryParse(inp, b) Then
    133. value = b
    134. Return True
    135. Else
    136. Return False
    137. End If
    138. End Function,
    139. Function(inp As String, ByRef value As Object)
    140. Dim b As Single
    141. If Single.TryParse(inp, b) Then
    142. value = b
    143. Return True
    144. Else
    145. Return False
    146. End If
    147. End Function,
    148. Function(inp As String, ByRef value As Object)
    149. Dim b As Double
    150. If Double.TryParse(inp, b) Then
    151. value = b
    152. Return True
    153. Else
    154. Return False
    155. End If
    156. End Function,
    157. Function(inp As String, ByRef value As Object)
    158. Dim b As Decimal
    159. If Decimal.TryParse(inp, b) Then
    160. value = b
    161. Return True
    162. Else
    163. Return False
    164. End If
    165. End Function,
    166. Function(inp As String, ByRef value As Object)
    167. Dim b As DateTime
    168. If DateTime.TryParse(inp, b) Then
    169. value = b
    170. Return True
    171. Else
    172. Return False
    173. End If
    174. End Function,
    175. Nothing,
    176. Function(inp As String, ByRef value As Object)
    177. value = inp
    178. Return True
    179. End Function}
    180. If dgl(CInt(typeCode)) <> Nothing Then
    181. Return dgl(CInt(typeCode)).Invoke(input, returnValue)
    182. Else
    183. Return False
    184. End If
    185. End Function


    Ansonsten würde folgender Code für die von TypeCode unterstützten Typen genügen:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Shared Function Parse(Of T)(ByVal input As String, ByRef returnValue As Object) As Boolean
    2. Return Parse(input, Type.GetTypeCode(GetType(T)), returnValue)
    3. End Function
    4. Public Shared Function Parse(ByVal input As String, ByVal typeCode As TypeCode, ByRef returnValue As Object) As Boolean
    5. Static dgl() As Parser = New Parser() {Nothing,
    6. Nothing,
    7. Function(inp As String, ByRef value As Object)
    8. Dim b As Boolean
    9. If Boolean.TryParse(inp, b) Then
    10. value = b
    11. Return True
    12. Else
    13. Return False
    14. End If
    15. End Function,
    16. Function(inp As String, ByRef value As Object)
    17. Dim b As Boolean
    18. If Boolean.TryParse(inp, b) Then
    19. value = b
    20. Return True
    21. Else
    22. Return False
    23. End If
    24. End Function,
    25. Function(inp As String, ByRef value As Object)
    26. Dim b As Char
    27. If Char.TryParse(inp, b) Then
    28. value = b
    29. Return True
    30. Else
    31. Return False
    32. End If
    33. End Function,
    34. Function(inp As String, ByRef value As Object)
    35. Dim b As SByte
    36. If SByte.TryParse(inp, b) Then
    37. value = b
    38. Return True
    39. Else
    40. Return False
    41. End If
    42. End Function,
    43. Function(inp As String, ByRef value As Object)
    44. Dim b As Byte
    45. If Byte.TryParse(inp, b) Then
    46. value = b
    47. Return True
    48. Else
    49. Return False
    50. End If
    51. End Function,
    52. Function(inp As String, ByRef value As Object)
    53. Dim b As Short
    54. If Short.TryParse(inp, b) Then
    55. value = b
    56. Return True
    57. Else
    58. Return False
    59. End If
    60. End Function,
    61. Function(inp As String, ByRef value As Object)
    62. Dim b As UShort
    63. If UShort.TryParse(inp, b) Then
    64. value = b
    65. Return True
    66. Else
    67. Return False
    68. End If
    69. End Function,
    70. Function(inp As String, ByRef value As Object)
    71. Dim b As Integer
    72. If Integer.TryParse(inp, b) Then
    73. value = b
    74. Return True
    75. Else
    76. Return False
    77. End If
    78. End Function,
    79. Function(inp As String, ByRef value As Object)
    80. Dim b As UInteger
    81. If UInteger.TryParse(inp, b) Then
    82. value = b
    83. Return True
    84. Else
    85. Return False
    86. End If
    87. End Function,
    88. Function(inp As String, ByRef value As Object)
    89. Dim b As Long
    90. If Long.TryParse(inp, b) Then
    91. value = b
    92. Return True
    93. Else
    94. Return False
    95. End If
    96. End Function,
    97. Function(inp As String, ByRef value As Object)
    98. Dim b As ULong
    99. If ULong.TryParse(inp, b) Then
    100. value = b
    101. Return True
    102. Else
    103. Return False
    104. End If
    105. End Function,
    106. Function(inp As String, ByRef value As Object)
    107. Dim b As Single
    108. If Single.TryParse(inp, b) Then
    109. value = b
    110. Return True
    111. Else
    112. Return False
    113. End If
    114. End Function,
    115. Function(inp As String, ByRef value As Object)
    116. Dim b As Double
    117. If Double.TryParse(inp, b) Then
    118. value = b
    119. Return True
    120. Else
    121. Return False
    122. End If
    123. End Function,
    124. Function(inp As String, ByRef value As Object)
    125. Dim b As Decimal
    126. If Decimal.TryParse(inp, b) Then
    127. value = b
    128. Return True
    129. Else
    130. Return False
    131. End If
    132. End Function,
    133. Function(inp As String, ByRef value As Object)
    134. Dim b As DateTime
    135. If DateTime.TryParse(inp, b) Then
    136. value = b
    137. Return True
    138. Else
    139. Return False
    140. End If
    141. End Function,
    142. Nothing,
    143. Function(inp As String, ByRef value As Object)
    144. value = inp
    145. Return True
    146. End Function}
    147. If dgl(CInt(typeCode)) <> Nothing Then
    148. Return dgl(CInt(typeCode)).Invoke(input, returnValue)
    149. Else
    150. Return False
    151. End If
    152. End Function

    Der Vorteil oder situationsbedingt evtl. auch Nachteil ist, dass ich ein Array mit Parser-Funktionen habe und über die (fast) sequentiell angeordnete TypeCode-Enumeration auf die Array-Einträge mit den Delegaten zugreife. Ist halt ein wenig mehr Code.

    Gruß
    ~blaze~
    Ich suchte eine Funktion für Strings ähnlich der üblichen Art TryParse:
    siehe folgendes Aufrufbeispiel:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. For Each i In externList 'externe Liste abgleichen
    2. If Not i.TryParse(dv.Table.Columns(colName).DataType()) Then Continue For
    3. '
    4. 'sonstiges
    5. '
    6. Next

    und habe nochmals ordentlich gegoogelt und bin da gelandet
    Hier werden generische Erweiterungsmethoden in C# präsentiert, die mit Reflection arbeiten...
    Ich habe mir da eine Kleinigkeit abgekupfert in stark abgekürzter Form...

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Module StringTryParse
    2. Private ReadOnly myMethods As New Dictionary(Of Type, MethodInfo)()
    3. <System.Runtime.CompilerServices.Extension()> _
    4. Public Function TryParse(S As String, T As Type) As Boolean
    5. If IsNothing(T) Then Return False
    6. Dim M As MethodInfo = Nothing
    7. SyncLock DirectCast(myMethods, ICollection).SyncRoot
    8. If Not myMethods.ContainsKey(T) Then
    9. Dim myFlags As BindingFlags = BindingFlags.Public Or BindingFlags.Static
    10. Dim pTypes As Type() = New Type() {GetType(String), T.MakeByRefType()}
    11. M = T.GetMethod("TryParse", myFlags, Nothing, pTypes, Nothing)
    12. If M IsNot Nothing Then
    13. If Not M.ContainsGenericParameters OrElse M.IsStatic OrElse M.ReturnType Is GetType(Boolean) Then
    14. Dim I As ParameterInfo() = M.GetParameters()
    15. If Not (I.Length = 2 AndAlso I(0).ParameterType Is GetType(String) _
    16. AndAlso I(1).ParameterType Is T.MakeByRefType()) Then M = Nothing
    17. Else
    18. M = Nothing
    19. End If
    20. End If
    21. myMethods.Add(T, M)
    22. End If
    23. End SyncLock
    24. M = myMethods(T) : If IsNothing(M) Then Return False
    25. Dim P As Object() = New Object() {S, Nothing}
    26. Return CBool(M.Invoke(Nothing, P))
    27. End Function
    28. End Module
    Jo, cooles Gerät - klassischer Hack - verwendet undokumentierte Methoden.
    Es scheint eine Public Shared TryParse - Methode der Typ-Klasse zu geben, die im Objectbrowser nicht angezeigt wird - die wird hier mit Reflection ausgepuhlt - könntest auch mal probieren, mit Strict Off - das wäre deutlich schneller.

    Deine Methode ist falsch benamt - sie muß Canparse heißen.
    Bei IsNothing(M) mussich schlucken, also ich würde formulieren: M Is Nothing.