2009-11-03 5 views
12

Gibt es eine bessere Möglichkeit zu testen, ob eine Zeichenfolge in eine andere Ganzzahl als die folgende konvertiert werden kann?Testen, ob eine Zeichenfolge in VB.NET als Ganzzahl umgewandelt werden kann

Public Function IsInt(ByVal value As Object) As Boolean 
    Try 
     Dim temp As Integer = CInt(value) 
     Return True 
    Catch ex As Exception 
     Return False 
    End Try 
End Function 

von "besser" ich meine weniger wortreich und/oder ohne eine Ausnahme.

TryParse wäre der Weg zu gehen, aber ich bin mit dem Compact Framework 2.0 und TryParse scheint nicht umgesetzt zu werden ....

Dank sowieso.

Es scheint, dass MarkJ korrekt ist und das Obige scheint funktional das gleiche wie IsNumeric zu sein, also nehme ich an, dass das meine Antwort ist. Ich weiß nicht, warum ich dachte, CInt sei strenger als IsNumeric. Ich denke, es ist besser, mit CInt Verse IsNumeric zu testen, da das die Funktion ist, die ich für die Konvertierung verwende?

+3

+1 für Ausnahmen im normalen Kontrollfluss vermieden werden folgen. – Heinzi

+1

Was, keine Vorschläge hier, um reguläre Ausdrücke zu verwenden? Ich bin geschockt! (http://stackoverflow.com/questions/223832/check-a-string-to-see-if-all-characters-are-hexadecimal-values) –

+0

@Michael Burr: Auf Ihre Anfrage habe ich einen Vorschlag hinzugefügt Verwenden regulärer Ausdrücke. Da TryParse nicht unterstützt wird, denke ich, dass Regex in diesem Fall die nächstbeste Option ist. –

Antwort

13

Sie können die in IsNumeric Funktion gebaut verwenden

Dim CanConvert as Boolean = IsNumeric(value) 

http://msdn.microsoft.com/en-us/library/6cd3f6w1(VS.71).aspx

+1

IsNumeric erlaubt $ und. was dazu führen kann, dass das Casting fehlschlägt. –

+0

In diesem Fall ist TryParse der Weg zu gehen –

+1

+1 @Booji Boy, Sie sind falsch. IsNumeric erlaubt '.' und' $ ', aber auch CInt (es rundet Bruchwerte ab). Ich habe mit dem Desktop-Framework überprüft - macht das Compact-Framework etwas anderes? – MarkJ

3

Wenn Sie Ausnahmen vermeiden möchten, können Sie sie mit einem regulären Ausdruck abgleichen, der vor der Konvertierung nur Ziffern zulässt.

+2

aber dann hätte ich zwei Probleme! ;-) –

4
Public Function IsInt(ByVal value As Object) As Boolean 
    Dim i As Integer 
    Return Integer.TryParse(Convert.ToString(value), i) 
End Function 
1
Dim s as String = "23" 
Dim i as Integer 
If Int32.TryParse(s, i) Then 
    ' String was a valid integer... ' 
End If 
5

Sie Integer.TryParse verwenden können, die eine Bool zurück angibt, ob die Konvertierung erfolgreich war oder nicht

1

Verwenden Sie die TryParse shared-Methode vom Integer-Typ.

Zum Beispiel:

Private Function CanStringBeCastAsInteger(ByVal myString As String) As Boolean 
    Dim myInt As Integer = 0 
    Return Integer.TryParse(myString, myInt) 
End Function 

Der Vorteil der TryParse Methode ist, dass es werfen vermeidet und anschließend eine Ausnahme zu fangen, wenn die Umwandlung fehlschlägt. Das Werfen und Abfangen von Ausnahmen ist eine teure Operation.

Die TryParse-Methode gibt nicht nur ein True/False-Ergebnis zurück, das Ihnen anzeigt, ob die Konvertierung erfolgreich ist oder nicht, sie gibt auch die resultierende Konvertierung in meinem Beispiel in dem myInt-Parameter für Sie zurück von Code.

0

Sie müssten Ihren eigenen Regex e.x .: Regex.IsMatch ("4354354", "\ d +") rollen und trotzdem den try/catch-Block als Backup verwenden.

+0

-1, sorry, aus ein paar Gründen.Try/Catch ist gut als Teil der Fehlerbehandlungslogik der Anwendung, aber nicht einfach als Backup, falls die Regex-Logik es vermisst. Die Regex dafür ist nicht so schwierig, dass Sie sich ihrer Richtigkeit nicht sicher sein können. Auch müssen Sie ablehnen, weil die Regex in Ihrem Beispiel nicht ausreichend ist. "A123Z" würde passieren, und "-10" würde fehlschlagen. –

2

Wenn Sie die Konvertierung nur selten durchführen, ist das, was Sie haben, in Ordnung (vorausgesetzt, Ihnen steht kein TryParse() zur Verfügung) - es wird sich nicht auf die Leistung auswirken.

Wenn Sie Millionen von Conversions durchführen und eine große Anzahl von Conversions möglicherweise fehlschlagen, könnte die Ausnahme, die Sie abfangen, ein Perf-Problem sein (möglicherweise).

Wenn Sie TryParse() nicht verwenden können, ist wahrscheinlich das Beste, was zu tun ist (perf-weise), einfach jedes Zeichen in der Zeichenfolge zu überprüfen und wenn es keine Ziffer ist, false zurück. Vergessen Sie nicht, ein mögliches negatives Vorzeichen und Gruppenseparatoren zu berücksichtigen (wenn Sie sie unterstützen möchten).

Andernfalls analysieren Sie die Zeichenfolge zu einem int, die in 99% der Fälle erfolgreich sein wird. Sie erhalten nur eine Ausnahme, wenn sie nicht passt.Wenn Sie die Ausnahme, die Parse() generieren könnte, wirklich vermeiden möchten, ist es nicht schwer, den Stich von Ziffern selbst zu analysieren und Fehler zurückzugeben, wenn er außerhalb des Bereichs liegt.

Jon Skeet hat eine schnelle Analyse dieser Zeit vor dem Rahmen TryParse() enthalten:

Nichts von alldem die Ausführlichkeit fixiert, though. Aber solange es eine in sich geschlossene Methode ist, gibt es kein Problem mit etwas Ausführlichkeit.

1

Hier ist etwas sehr ähnlich zu dem, was Sie bereits haben, sondern verwendet die Convert-Klasse statt CType und verwendet nicht TryParse

Public Function IsInt(ByVal value As Object) As Boolean 
    Try 
     Convert.ToInt32(value) 
     Return True 
    Catch ex As System.FormatException 
     Return False 
    End Try 
End Function 
+0

Warum die Klasse 'Convert' verwenden? Es hat keinen Vorteil. Tatsächlich ist die 'Convert'-Klasse ziemlich überflüssig (außer wenn Sie eine Zahl in einer anderen Basis als 10 darstellen müssen und 16 die einzigen Basen sind, die von' ToString' unterstützt werden). –

6

Seit TryParse isn't supported auf dem Compact Framework, regex ist Ihre nächste beste Option.

Das erste Beispiel lässt keine Dezimalstellen zu. Der zweite tut.

Wenn Sie wissenschaftliche Notation zulassen müssen, müssen Sie es ein wenig mehr zwicken. Es ist wirklich nicht so schlimm. Sie haben den Anfang der Zeichenfolge ^, ein optionaler Strich -?, eine oder mehrere Ziffern \d+, eine nicht einfangende Gruppe (?:), die nach einem einzelnen Dezimalpunkt \. und einer oder mehreren Ziffern \d+ sucht. Ein weiterer ?, um entweder Null oder eine Instanz der nicht einfangenden Gruppe und dann das Ende der Zeichenfolge $ zu ermöglichen.

Edit: Eine Sache, die ich nicht über dachte vor: Diese Methode ist ein wenig ungenau, weil Sie eine wirklich große Zahl bekommen konnten, die numerisch eine gültige ganze Zahl ist aber nicht auf eine Int32 umgewandelt werden. Wenn das möglich ist, können Sie die Anzahl der Zeichen beschränken. Anstelle von \d+ könnten Sie beispielsweise \d{1,8} tun.

+0

+1 für ein anderes Compact Framework getcha –

+2

Die Methode ist auch nicht regional bewusst - einige Kulturen verwenden Komma ',' für Dezimaltrennzeichen nicht Punkt '.' – MarkJ

+0

@MarkJ, guter Punkt. –

-1

Sie als

If myString <> "" And IsNumeric(myString) = True Then 

     If CDbl(myString) - Int(CDbl(myString)) > 0 Then 
      .... myString is integer 
     End If 

    End If