10 Stimmen

Was ist das interne Format eines .NET-Strings?

Ich mache gerade einen ziemlich string-manipulationsintensiven Code in C#.NET und wurde neugierig auf einige Artikel von Joel Spolsky, die ich vor einiger Zeit gelesen hatte:

http://www.joelonsoftware.com/articles/fog0000000319.html
http://www.joelonsoftware.com/articles/Unicode.html

Und wie macht .NET das? Zwei Bytes pro Zeichen? Es gibt einige Unicode-Zeichen^H^H^H^H^H^H-Codepunkte, die mehr als das benötigen. Und wie wird die Länge kodiert?

18voto

Johnno Nolan Punkte 28357

Bevor Jon Skeet auftaucht, hier noch ein Link zu seinem ausgezeichneter Blog über Saiten in C#.

Zumindest in der derzeitigen Implementierung belegen Strings 20+(n/2)*4 Bytes (wobei der Wert von n/2 abgerundet wird), wobei n die Anzahl der Zeichen im String ist. Der Stringtyp ist insofern ungewöhnlich, als die Größe des Objekts selbst variiert

12voto

Reed Copsey Punkte 536986

.NET verwendet UTF-16 .

Von System.String auf MSDN :

"Jedes Unicode-Zeichen in einer Zeichenkette wird durch einen Unicode-Skalarwert definiert, der auch als Unicode-Codepunkt oder als Ordinalwert (numerisch) des Unicode-Zeichens bezeichnet wird. Jeder Codepunkt wird mit der UTF-16-Kodierung kodiert, und der numerische Wert jedes Elements der Kodierung wird durch ein Char-Objekt dargestellt."

1voto

booFar Punkte 51

Das String-Objekt ist ziemlich kompliziert, um ein kurzes Beispiel zu geben und einen gegebenen Text in eine Zeichenkette zu kodieren, wobei der resultierende Speicherinhalt als eine Folge von Bytewerten angezeigt wird.

Ein String-Objekt stellt Text als eine Folge von UTF-16-Codeeinheiten dar. Es ist eine sequentielle Sammlung von System.Char-Objekten, von denen jedes einer UTF-16-Codeeinheit entspricht. Ein einzelnes Char-Objekt repräsentiert normalerweise einen einzelnen Codepunkt. Ein Codepunkt kann mehr als ein kodiertes Element erfordern, d. h. mehr als ein Char-Objekt (zusätzliche Codepunkte (oder Surrogatpaare) und Grapheme). Hinweis: UTF-16 ist eine Kodierung mit variabler Breite.

Die Länge der Zeichenkette wird als Eigenschaft des String-Objekts im Speicher abgelegt. Hinweis: Ein String-Objekt kann eingebettete Null-Zeichen enthalten, die als Teil der Länge des Strings zählen (im Gegensatz zu C und C++, wo ein Null-Zeichen das Ende eines Strings anzeigt, so dass die Länge nicht zusätzlich gespeichert werden muss). Das interne Zeichen-Array, in dem die Char-Objekte gespeichert sind, kann tatsächlich länger sein als die Länge der Zeichenkette (was auf die Zuweisungsstrategie zurückzuführen ist).

Wenn Sie Schwierigkeiten haben, die richtige Kodierung zu finden (weil Sie keine Eigenschaft mit dem Namen System.Text.Encoding.UTF16 finden können), ist UTF-16 eigentlich System.Text.Encoding.Unicode, wie in diesem Beispiel verwendet:

string unicodeString = "pi stands for \u03a0";
byte[] encoded = System.Text.Encoding.Unicode.GetBytes(unicodeString);

Der Konstruktor Encoding.Unicode erzeugt ohne Parameter ein UnicodeEncoding-Objekt mit der Little-Endian-Byte-Reihenfolge. Die Klasse UnicodeEncoding (die die UTF-16-Kodierung implementiert) kann auch Big Endian verarbeiten (unterstützt auch die Verarbeitung einer Byte Order Mark). Die native Bytereihenfolge der Intel-Plattform ist Little Endian, so dass es für .NET (und Windows) wahrscheinlich effizienter ist, Unicode-Strings in diesem Format zu speichern.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X