Tamam, .Net ve C # 'de tüm dizeler UTF-16LE olarak kodlanmıştır . A string
, bir karakter dizisi olarak saklanır. Her char
biri 2 bayt veya 16 bitlik depolamayı kapsüller.
Tek bir harf, karakter, glif, sembol veya noktalama işareti olarak "kağıtta veya ekranda" gördüğümüz şey, tek bir Metin Öğesi olarak düşünülebilir. Unicode Standardı Ek # 29 UNICODE METİN BÖLÜMÜ'nde açıklandığı gibi , her Metin Öğesi bir veya daha fazla Kod Noktası ile temsil edilir. Kapsamlı bir Kod listesi burada bulunabilir .
Her bir Kod Noktasının bir bilgisayar tarafından dahili gösterimi için ikiliye kodlanması gerekir. Belirtildiği gibi, her biri char
2 bayt depolar. Kod Noktaları veya daha düşük U+FFFF
tek bir yerde saklanabilir char
. Yukarıdaki Kod Noktaları U+FFFF
, tek bir Kod Noktasını temsil etmek için iki karakter kullanılarak bir vekil çifti olarak saklanır.
Şu anda çıkarsayabileceğimizi bildiğimiz göz önüne alındığında, bir Metin Öğesi bir char
olarak, iki karakterden oluşan bir Vekil Çifti olarak veya Metin Öğesi birden fazla Kod Noktasıyla temsil ediliyorsa, tek karakterlerin ve Vekil Çiftlerinin bazı kombinasyonlarının bir arada saklanabilir . Bu yeterince karmaşık değilmiş gibi, bazı Metin Öğeleri , Unicode Standard Annex # 15, UNICODE NORMALIZATION FORMS'da açıklandığı gibi farklı Kod Noktası kombinasyonlarıyla temsil edilebilir .
Perde arkası
Dolayısıyla, oluşturulduklarında aynı görünen dizeler aslında farklı bir karakter kombinasyonundan oluşabilir. Bu tür iki dizinin sıralı (bayt bayt) karşılaştırması bir farkı tespit eder, bu beklenmedik veya istenmeyen olabilir.
.Net dizelerini yeniden kodlayabilirsiniz. böylece aynı Normalleştirme Formunu kullanırlar. Normalleştirildikten sonra, aynı Metin Öğelerine sahip iki dize aynı şekilde kodlanacaktır. Bunu yapmak için string.Normalize işlevini kullanın . Ancak, bazı farklı Metin Öğelerinin birbirine benzediğini unutmayın. : -s
Öyleyse, tüm bunlar soruyla ilgili olarak ne anlama geliyor? Metin Öğesi '𠈓'
, tek Kod Noktası U + 20213 cjk birleşik ideograflar uzantısı b ile temsil edilir . Bu, tek char
olarak kodlanamayacağı ve iki karakter kullanılarak Vekil Çifti olarak kodlanması gerektiği anlamına gelir . Bu yüzden string b
bir tane char
daha uzun string a
.
Eğer güvenilir bir şekilde (uyarıya bakın) bir içindeki Metin Öğelerinin sayısını saymanız string
gerekiyorsa,
System.Globalization.StringInfo
sınıfı şu şekilde kullanmalısınız.
using System.Globalization;
string a = "abc";
string b = "A𠈓C";
Console.WriteLine("Length a = {0}", new StringInfo(a).LengthInTextElements);
Console.WriteLine("Length b = {0}", new StringInfo(b).LengthInTextElements);
çıktı vermek,
"Length a = 3"
"Length b = 3"
beklenildiği gibi.
Uyarı
Unicode Metin Segmentasyonunun StringInfo
ve TextElementEnumerator
sınıflarında .Net uygulaması genel olarak yararlı olmalı ve çoğu durumda arayanın beklediği bir yanıt verecektir. Bununla birlikte, Unicode Standardı Ek # 29'da belirtildiği gibi , "Kullanıcı algılarını eşleştirme hedefi her zaman tam olarak yerine getirilemez çünkü metin tek başına her zaman sınırları belirsiz bir şekilde karar vermek için yeterli bilgi içermemektedir."