2017-09-20 5 views
3

Was ist hier los?String.Split entfernt den geteilten Text nicht, nur der erste Buchstabe

issue.CallAction hat den folgenden Wert:

"Blah blah - WebSite - 9/20/2017 - Containers remaining changed to 0." 

Splitting auf sich, etwa so:

issue.CallAction.Split("Containers remaining changed to ").ToList() 

kehrt mehr als 1 string Element (wie in diesem Fall zu erwarten), aber die Elemente sind:

  1. Blah blah - WebSite - 9/20/2017 -
  2. ontainers remaining changed to 0.

Es war mein Verständnis, dass Split die gesamte Zeichenfolge ersetzt es, dass Sie spalten doch nur die ersten Buchstaben zu ersetzen.

Was gibt?

Hier ist ein Screenshot des Compilers mit einem String-Trennzeichen glücklich. Beachten Sie die Abwesenheit des wütenden roten Kringel:

Screenshot of the compiler happily allowing a string separator:

+2

ich es vielleicht dachte irgendwie die 'string' als' char [] vorging 'an die' String.Split (params char [] separator) 'overload, aber' "Blah blah - WebSite - 20.09.2017 - Container bleiben auf 0 geändert.". Split ("Containers restful" wird geändert) .ToList(); 'kann nicht mit Fehler kompiliert werden 'Argument 1: kann nicht von 'string' in 'char' auf .NET konvertieren 4.7. Im Nachhinein implementiert 'string'' IEnumerable ', aber' .ToCharArray() 'würde benötigt, um es zu einem' char [] 'zu machen. – BACON

+0

Genau mein Gedanke auch, weil es sich so verhält. Ich bin in .net 4.5.1 (ich nehme an, ich sollte das markieren). Ich frage mich, ob es eines der Dinge ist, die sie bis 4.7 verpasst haben? Es gibt einen großen Sprung zwischen 4,5 und 4,7. – MetalPhoenix

+0

Ich bekomme den gleichen Compiler-Fehler, wenn ich gegen Visual Studio 2017 v15.5 Visual Studio 2017 vs. – BACON

Antwort

3

Es sieht aus wie es das Trennzeichen als Char behandeln. Zumindest in Visual Studio 2017/.NET 4.5, C#, das ist, was ich verwende, sowie the current version keine

string Split(string separator) 

ist so würden Sie haben eine Reihe von Separatoren zu schaffen und die ersten bevöl .

Try this:

 string s = "Blah blah - WebSite - 9/20/2017 - Containers remaining changed to 0."; 

     string[] separator = { "Containers remaining changed to " }; 
     string[] splitted = s.Split(separator, StringSplitOptions.None); 

EDIT:

Ich habe VB nicht in einigen Jahren verwendet, so hatte ich hier etwas neu lernen zu tun. Die Ausgabe dieses Beispielprogramm sagt mir, dass VB ruhig ein String in eine Char nötigt, wenn ein Char für genannt wird:

Sub PrintAChar(c As Char) 
    Console.WriteLine("Printing your character: '" + c + "'") 
End Sub 

Sub Main() 
    PrintAChar("B")    ' Prints 'B' 
    PrintAChar("Bob Was Here.") ' Also prints 'B' 
End Sub 

See @ Heinzi wichtigen Kommentar unten für eine Best Practice.

+0

Huh, das ... funktioniert. Wenn Sie herausfinden, warum es keinen Fehler gibt, lassen Sie es mich bitte wissen. Es sollte passen, da der Compiler mit einer Zeichenfolge anstelle eines Arrays in Ordnung scheint. Danke, übrigens. – MetalPhoenix

+2

Warum gibt es keine 'Split (String Separator)' stört mich zu keinem Ende. Warum es so aussieht, als würde man die Saite leise in einen Char umwandeln, ist im Moment ein Rätsel. Bleib dran. Ein bisschen mehr Kontext kann helfen, wenn sich diese Dinge in verschiedenen Situationen anders verhalten. Liegt dies in einer '.cs' Datei oder einem Code dahinter? Welche Version von .NET und welche Version von Visual Studio? –

+0

.aspx.vb-Datei, .net 4.5.1, VS 2013 – MetalPhoenix

2

Ist es nicht interessant, wie derselbe Code sowohl als gültiges C# als auch als VB.NET erscheinen kann und dennoch drastisch unterschiedliche Ergebnisse liefert? Ich bemerkte das Fehlen eines abschließenden Semikolons, nahm aber an, dass es nur ein Kopier- und Einfüge-Artefakt war.

Verwendung des folgenden Codes ...

Dim text As String = "Blah blah - WebSite - 9/20/2017 - Containers remaining changed to 0." 
Dim list1 As List(Of String) = text.Split("Containers remaining changed to ").ToList() 

IntelliSense ... zeigt an, dass die Überlast String.Split(ParamArray() separator as Char()) genannt wird (the MSDN documentation umfasst die ParamArray modifier), ...

VB.NET IntelliSense for String passed to String.Split method

Bei der Ausführung list1 dann enthält folgende Komponenten:

list1(0) = "Blah blah - WebSite - 9/20/2017 - " 
list1(1) = "ontainers remaining changed to 0." 

Wenn Sie es mit dieser scheinbar äquivalenten Syntax schreiben ...

Dim list2 As List(Of String) = text.Split("C", "o", "n", "t", "a", "i", "n", "e", "r", "s", " ", "r", "e", "m", "a", "i", "n", "i", "n", "g", " ", "c", "h", "a", "n", "g", "e", "d", " ", "t", "o", " ").ToList() 
Dim list3 As List(Of String) = text.Split("Containers remaining changed to ".ToCharArray()).ToList() 

... IntelliSense beide zeigt .Split() Anrufe lösen sich auf die gleiche Überlast wie oben, aber die Ergebnisse für list2 sind sehr diff Erent ...

list2(0) = "Bl" 
list2(1) = "" 
list2(2) = "" 
list2(3) = "bl" 
list2(4) = "" 
list2(5) = "" 
list2(6) = "-" 
list2(7) = "W" 
list2(8) = "bS" 
list2(9) = "" 
list2(10) = "" 
list2(11) = "" 
list2(12) = "-" 
list2(13) = "9/20/2017" 
list2(14) = "-" 
list2(15) = "" 
list2(16) = "" 
list2(17) = "" 
list2(18) = "" 
list2(19) = "" 
list2(20) = "" 
list2(21) = "" 
list2(22) = "" 
list2(23) = "" 
list2(24) = "" 
list2(25) = "" 
list2(26) = "" 
list2(27) = "" 
list2(28) = "" 
list2(29) = "" 
list2(30) = "" 
list2(31) = "" 
list2(32) = "" 
list2(33) = "" 
list2(34) = "" 
list2(35) = "" 
list2(36) = "" 
list2(37) = "" 
list2(38) = "" 
list2(39) = "" 
list2(40) = "" 
list2(41) = "" 
list2(42) = "" 
list2(43) = "" 
list2(44) = "" 
list2(45) = "" 
list2(46) = "" 
list2(47) = "0." 

... und das gleiche gilt für list3. Dies ist eigentlich, was wir erwartet hätten list1, um alle zusammen zu sein, da es sich auf einen der Zeichen in der übergebenen String teilen würde.

Warum passiert das? Das ist interessant für mich, obwohl ich kein VB.NET-Typ bin, also ist dies vielleicht ein allgemeines Wissen/Fallstrick. Wenn wir einen Blick auf what the compiler produces nehmen sehen wir folgende:

Dim text As String = "Blah blah - WebSite - 9/20/2017 - Containers remaining changed to 0." 
Dim arg_13_0 As String = text 
Dim expr_0E As Char() = New Char(0) {} 
expr_0E(0) = "C"c 
Dim list As List(Of String) = arg_13_0.Split(expr_0E).ToList(Of String)() 
Dim arg_31_0 As String = text 
Dim expr_26 As Char() = New Char(31) {} 
RuntimeHelpers.InitializeArray(expr_26, fieldof(<PrivateImplementationDetails>.B46FB904AE74F7001A264BB77882D707B0E9ECC7).FieldHandle) 
Dim list2 As List(Of String) = arg_31_0.Split(expr_26).ToList(Of String)() 
Dim list3 As List(Of String) = text.Split("Containers remaining changed to ".ToCharArray()).ToList(Of String)() 

Das heißt, im Fall von list2 ist es vorbei einen Char Array, bestehend aus all den Char s in "Containers remaining changed to ", doch im Fall von list1 es ist Passing ein Char Array bestehend aus nur die erste Char, "C"c! Sprechen Sie über die unterschiedlichen Ergebnisse von ähnlich aussehenden Code ...

Ich kann nicht ein einziges Dokument finden, die alle diese Punkte verbindet, aber im Grunde genommen String wird implicitly converted zu Char(), die die CChar conversion function nennt, die nur zurückgibt die erste Char. Somit sind die folgenden vier Zeilen äquivalent:

Dim list1a As List(Of String) = text.Split("Containers remaining changed to ").ToList() 
Dim list1b As List(Of String) = text.Split(CChar("Containers remaining changed to ")).ToList() 
Dim list1c As List(Of String) = text.Split("C").ToList() 
Dim list1d As List(Of String) = text.Split("C"c).ToList() 
+0

Das ist absolut verrückt, dass es das tun würde. Meistens sind C# und VB gleichwertig genug, dass Sie dies nicht wissen oder sich darum kümmern müssen. Danke für die Details sowie die Compiler-Code-Site. – MetalPhoenix

Verwandte Themen