.NET Framework 4.5からSyste.Globalization名前空間にSortVersionと言うクラスが追加されました。
MSDNライブラリでは以下のように書かれています。
文字列を比較および並べ替えに使用される Unicode バージョンに関する情報を提供します。
何のことかよくわかりませんが、何となくWindowsがソートに使用している照合順序の元になったUNICODEのバージョンを持っていそうなクラスです。
以下のようなコードを書いて動きを見てみます。
namespace ConsoleApplication1 { using System; using System.Globalization; internal class Program { #region Methods private static void Main() { var hoge = CultureInfo.CurrentCulture.CompareInfo; var sortVersion = hoge.Version; //SortVesionクラスを取得する Console.WriteLine(CultureInfo.CurrentCulture.Name); Console.WriteLine(CultureInfo.CurrentCulture.LCID); Console.WriteLine(sortVersion.FullVersion); Console.WriteLine(sortVersion.SortId); Console.ReadLine(); } #endregion } }
先ほどのMSDNの説明文からすると、SortVersion.FullVersionはUNICODEのバージョンを返してくれそうな気がしますが。
Windows 8.1で実行した結果は以下の通り。
ja-JP 263185 393742 00000036-57ee-1e5c-00b4-d0000bb1e11e
下から2番目の数字がFullVersioプロパティの値。大きく期待からはずれた一見訳のわからない数字になっていますね。期待した数値と全く異なるのでちょっとパニックです。
ただUNICODEバージョンを返しているわけでは無さそうです。
当然のことながら、この数字自体にはそれなりに意味があるはずだし、このプロパティにCultureInfoクラスのCurrentCultureプロパティ内で適切な値を挿入する際に使用したWindowsのAPIが有るはずです。
そこで、調べてみました。
Globalization 関係のAPIでVista/2008で、GetNLSVersion, GetNLSVersionExという関数が追加されています。これらはLCIDなどを引数にとって照合順序に関する情報をNLSVERSIONINFO構造体に取得する関数で、この構造体の中にDWORD dwNLSVersionと言う変数があったので、これが、SortVersionのFullVersionプロパティが持つ値だろうと推測できます。
さて、このDWORDの値の意味ですが、やはりただのUNICODEのバージョンではないようで、以下のMSDNライブラリのドキュメントに詳しく書かれています。
かいつまんでまとめると、Vista以降Windowsが持つ照合順序が変更になっているが、これが変更になるとユーザー側のアプリケーションで何らかのインデックスを持っているようなケースだと、インデックスの変更が必要になる場合があるので、変わったことが解るように照合順序のバージョン情報を用意して、それをを返すAPIを追加しましたって事のようです。
Windowsのバージョンごとに対応Unicodeのバージョンが変わり、そのため、Unicodeの文字が持つ重みづけ設定を元にWindowsの照合順序が設定され、照合順序の設定自体が変わるのだけど、XPまでは必要性が薄かったし、あんまり注目されてこなかったのでこのような情報・関数がなかったのでしょう。
Windows 8.1ではSortVersion.FullVersionの値は0x0006020eと言う値を返してきます。
さて、もう少し気になるのが、元々のSourtVersionクラスのMSDNライブラリの記述にあっさりさらっと書かれている記述ですが、.NET 4.5からは.NET FrameworkでSortなどの文字列比較に使われる照合順序の元になるUNICODEのバージョンがWindowsのバージョンで変わることになり、同じ.NET 4.5をターゲットにアプリケーションを作成しても、Windows 7ではUNICODE 5.0で比較され、、Windows 8ではUnicode 6.0で比較されることになります。(.NET 4.0であれば、Windowsのバージョンに関係なくUnicode 5.0での比較となるようです。)
つまり、.NET 4.5をターゲットにビルドされたアセンブリでは、同じアセンブリでもOSによってソートや、文字比較の結果が異なる可能性が出てきます。特に日本語関連で良くありそうなことでは、携帯向け絵文字などの比較やソートがWindows 7ではうまくいかないケースも出てくると思いますので、よくよく検証してみましょう。(もっともWindows自体がUnicode 6.0に対応するのがWindows 8からなので仕方ないのですが。)
ということで、あまり普段気にしていないかもしれませんが、SQL ServerのようなRDBMSだけでは無く、Windowsでも照合順序に気を付けていた方が良いケースはあるので注意しましょうね。
コメント
Kazushi Kamegawa liked this on Facebook.