Ich konvertiere etwas von VB in C #. Ein Problem mit der Syntax dieser Anweisung:
if ((searchResult.Properties["user"].Count > 0))
{
profile.User = System.Text.Encoding.UTF8.GetString(searchResult.Properties["user"][0]);
}
Ich sehe dann folgende Fehler:
Argument 1: Konvertierung von 'Objekt' in 'Byte []' nicht möglich
Die beste überladene Methodenübereinstimmung für 'System.Text.Encoding.GetString (byte [])' enthält einige ungültige Argumente
Ich habe versucht, den Code basierend auf diesem Beitrag zu korrigieren , aber immer noch keinen Erfolg
string User = Encoding.UTF8.GetString("user", 0);
Irgendwelche Vorschläge?
searchResult.Properties["user"][0]
? Versuchen Sie esbyte[]
zuerst zu(byte[])
im searchResult?Properties["user"][0]
ist. Wenn Sie sicher sind , ist es ein Byte - Array , dann können Sie wie diese werfenprofile.User = System.Text.Encoding.UTF8.GetString((byte[])searchResult.Properties["user"][0]);
Antworten:
Wenn Sie bereits ein Byte-Array haben, müssen Sie wissen, welche Art von Codierung verwendet wurde, um es in dieses Byte-Array zu verwandeln.
Wenn das Byte-Array beispielsweise folgendermaßen erstellt wurde:
Sie müssen es wieder in eine Zeichenfolge wie die folgende umwandeln:
Wenn Sie in dem von Ihnen geerbten Code die Codierung finden, die zum Erstellen des Byte-Arrays verwendet wurde, sollten Sie festgelegt werden.
quelle
Fügen Sie zunächst den
System.Text
Namespace hinzuVerwenden Sie dann diesen Code
Hoffe es zu beheben!
quelle
Sie können auch eine Erweiterungsmethode verwenden , um dem
string
Typ eine Methode wie folgt hinzuzufügen :Und benutze es wie folgt:
quelle
ToASCIIByteArray
. Ich hasse es, wenn ich herausfinde, dass eine Bibliothek, die ich verwende, ASCII verwendet, und ich gehe davon aus, dass sie UTF-8 oder etwas Moderneres verwendet.quelle
quelle
Warum Encoding.Default nicht verwendet werden sollte ...
@ Randalls Antwort verwendet
Encoding.Default
, aber Microsoft warnt davor :Verwenden Sie
Encoding.Default.WindowsCodePage
(in meinem Fall 1250 - und leider gibt es keine vordefinierte Klasse der CP1250-Codierung, aber das Objekt kann als abgerufen werdenEncoding.GetEncoding(1250)
), um die Standardcodierung zu überprüfen .Encoding.ASCII
ist 7bit, also funktioniert es auch nicht, in meinem Fall:... und warum stattdessen UTF-8-Codierung verwendet werden sollte ...
Die Standardcodierung ist irreführend: .NET verwendet UTF-8 überall als Standard (8-Bit-Codierungen sind Ende des 20. Jahrhunderts veraltet, überprüfen Sie dh
Console.OutputEncoding.EncodingName
*), sodass jede im Code definierte Konstante standardmäßig UTF-8-codiert ist Dieser sollte verwendet werden, es sei denn, die Datenquelle hat eine andere Codierung.* Dies ist in meinem Fall UTF-8, was eine direkte Lüge ist:
chcp
Von der Windows-Konsole (cmd) wird 852 zurückgegeben - und dies sollte nicht geändert werden, da bei lokalisierten Systembefehlen (wie Ping) diese Codepage fest codiert istBefolgen Sie die Empfehlung von Microsoft:
Encoding.UTF8
Von anderen empfohlen wird eine Instanz der UTF-8-Codierung, die auch direkt oder als verwendet werden kann... aber es wird nicht immer verwendet
Die Codierung für Byte-Arrays sollte in westlichen Ländern in Unicode "nur funktionieren". Sobald Sie Ihr Programm jedoch in weniger unterstützte Regionen (wie hier in Osteuropa) verschieben, ist dies ein echtes Chaos: In der Tschechischen Republik wird Windows standardmäßig verwendet (im Jahr 2020!) MS nicht Standard 852 (auch bekannt als Latin-2) für Konsole, 1250 als Windows OEM, UTF-8 (65001) als .NET (und andere) neuer Standard und wir sollten bedenken, dass einige westliche EU 8bit Daten sind noch im Jahr 1252, während der alte 8-Bit-Weststandard für Osteuropa ISO-8859-2 war (auch bekannt als Latin-2, aber NICHT das gleiche Latin-2 wie 852). Die Verwendung von ASCII bedeutet Text voller Tofu und '?' Hier. Stellen Sie UTF-8 also bis zur Hälfte des 21. Jahrhunderts explizit ein .
quelle
Aufbauend auf Alis Antwort würde ich eine Erweiterungsmethode empfehlen, mit der Sie optional die Codierung übergeben können, die Sie verwenden möchten:
Und benutze es wie folgt:
quelle
Encoding encoding = Encoding.Default
zu einem Fehler bei der Kompilierung führt:CS1736 Default parameter value for 'encoding' must be a compile-time constant
Der folgende Ansatz funktioniert nur, wenn die Zeichen 1 Byte groß sind. (Standard-Unicode funktioniert nicht, da es 2 Bytes sind)
Einfach halten
quelle
char
undstring
sind per Definition UTF-16.string
und daher UTF-16. UTF-16 ist nicht die Standardeinstellung. es gibt keine Wahl. Sie teilen sich dann inchar[]
UTF-16-Codeeinheiten auf. Sie rufen dann Convert.ToByte (Char) auf , das zufällig U + 0000 in U + 00FF in ISO-8859-1 konvertiert und alle anderen Codepunkte entstellt.char
, 16 Bit zu sein und dieConvert.ToByte()
Hälfte davon wegzuwerfen.benutze das
quelle
Eine Verfeinerung der Bearbeitung von JustinStolle (Eran Yogevs Verwendung von BlockCopy).
Die vorgeschlagene Lösung ist in der Tat schneller als die Verwendung der Codierung. Das Problem ist, dass es nicht zum Codieren von Byte-Arrays mit ungleicher Länge funktioniert. Wie angegeben, wird eine Out-of-Bound-Ausnahme ausgelöst. Wenn Sie die Länge um 1 erhöhen, bleibt beim Dekodieren aus einem String ein nachfolgendes Byte übrig.
Für mich kam die Notwendigkeit , als ich zu kodieren von wollte
DataTable
zuJSON
. Ich suchte nach einer Möglichkeit, Binärfelder in Strings zu codieren und von String zurück zu zu decodierenbyte[]
.Ich habe daher zwei Klassen erstellt - eine, die die obige Lösung umschließt (beim Codieren aus Zeichenfolgen ist dies in Ordnung, da die Längen immer gerade sind), und eine andere, die das
byte[]
Codieren übernimmt .Ich habe das Problem der ungleichmäßigen Länge gelöst, indem ich ein einzelnes Zeichen hinzugefügt habe, das mir sagt, ob die ursprüngliche Länge des binären Arrays ungerade ('1') oder gerade ('0') war.
Wie folgt:
quelle
Diese Frage wurde ausreichend oft beantwortet, aber mit C # 7.2 und der Einführung des Span-Typs gibt es eine schnellere Möglichkeit, dies in unsicherem Code zu tun:
Beachten Sie, dass die Bytes eine UTF-16-codierte Zeichenfolge darstellen (in C # -Land "Unicode" genannt).
Einige schnelle Benchmarking-Tests zeigen, dass die oben genannten Methoden ungefähr fünfmal schneller sind als die Implementierungen Encoding.Unicode.GetBytes (...) / GetString (...) für mittelgroße Zeichenfolgen (30-50 Zeichen) und sogar noch schneller für größere Zeichenfolgen. Diese Methoden scheinen auch schneller zu sein als die Verwendung von Zeigern mit Marshal.Copy (..) oder Buffer.MemoryCopy (...).
quelle
Wenn das Ergebnis von 'searchResult.Properties ["user"] [0]' eine Zeichenfolge ist:
Der entscheidende Punkt ist, dass die Konvertierung eines Strings in ein Byte [] mit LINQ erfolgen kann:
Und umgekehrt:
quelle
Hat jemand einen Grund, dies nicht zu tun?
quelle
Convert.ToByte(char)
funktioniert nicht so wie du denkst. Das Zeichen'2'
wird in das Byte konvertiert2
, nicht in das Byte, das das Zeichen darstellt'2'
. Verwenden Siemystring.Select(x => (byte)x).ToArray()
stattdessen.Das hat bei mir funktioniert
quelle
Sie können die MemoryMarshal-API verwenden , um eine sehr schnelle und effiziente Konvertierung durchzuführen.
String
wird implizit umgewandeltReadOnlySpan<byte>
, alsMemoryMarshal.Cast
entwederSpan<byte>
oderReadOnlySpan<byte>
als Eingabeparameter akzeptiert .Der folgende Benchmark zeigt den Unterschied:
quelle
Diese Arbeit für mich, danach konnte ich mein Bild in ein Bytea-Feld in meiner Datenbank konvertieren.
quelle