C#でGUID(128bit長の一意の識別子)を生成するには、標準ライブラリ内のGuidクラス(System名前空間内)を使用します。
using System; public static void Main(string[] args) { Guid id = Guid.NewGuid(); Console.WriteLine(id.ToString()); // c1b2e279-5d98-45d3-8864-55bcda484695 }
生成したGUIDを文字列として取り出すためにGuidにはToString()メソッドが以下の3種類用意されています。
Signature | Description |
---|---|
ToString() | デフォルトの文字列取得を行う。(冒頭の通り) |
ToString(string format) | 書式を指定して文字列を取得する。 |
ToString(string format, IFormatProvider provider) | 普通使わないカスタム書式の指定 |
このうち、2番目のstring formatを指定するメソッドで、指定できる書式の種類と内容を紹介したいと思います。
指定できる書式と出力
使用できるフォーマットは以下の通り。
書式 | 使用例 | 出力結果 | 説明 |
---|---|---|---|
"D" もしくは "d" | ToString("D") | 73a7b7b0-4653-4367-bec0-4f667b936421 | 桁区切りにハイフン(引数なしToStringと同じ内容) |
"N" もしくは "n" | ToString("N") | 73a7b7b046534367bec04f667b936421 | 桁区切り無し |
"B" もしくは "b" | ToString("B") | {73a7b7b0-4653-4367-bec0-4f667b936421} | Dに加え前後に中括弧 |
"P" もしくは "p" | ToString("P") | (73a7b7b0-4653-4367-bec0-4f667b936421) | Dに加え前後に丸括弧 |
"X" もしくは "x" | guid.ToString("X") | {0x73a7b7b0,0x4653,0x4367,{0xbe,0xc0,0x4f,0x66,0x7b,0x93,0x64,0x21}} | int-short-shortの数列と各バイト |
Xとかデバッグ目的以外には使用しない変わった出力になります。これはいちいちToBinary()してforeachしないでも同様の結果が得られることを表します。
また、上記以外の文字を指定をするとご丁寧にも以下のメッセージが表示されます。
型 'System.FormatException' のハンドルされていない例外が mscorlib.dll で発生しました 追加情報: 書式文字列に指定できるのは "D"、"d"、"N"、"n"、"P"、"p"、"B"、"b"、"X"、または "x" のみです。
GUIDオブジェクト同士の比較
Guidどうしの比較はCompareToメソッドを使用します。間違ってもToString()した結果を文字列比較しないようにしましょう。(滅茶苦茶効率が悪いです。)
Guid a = Guid.NewGuid(); Guid b = Guid.NewGuid(); int i = a.CompareTo(b); // 比較結果は整数の大小で取得できる。
効率が悪いと言ったので計測結果を以下に示します。
計測内容は、2つのGUIDを作成して同値かどうかを100万回比較しました。結論から言うとToStringで文字列比較すると16倍遅かったです。
internal static void Main(string[] args) { var a = new Stopwatch(); var b = new Stopwatch(); for (int i = 0; i < 1000000; i++) { var aid = Guid.NewGuid(); var bid = Guid.NewGuid(); a.Start(); if (aid.CompareTo(bid) == 0) Console.WriteLine("おなじ"); a.Stop(); b.Start(); if (aid.ToString() == bid.ToString()) Console.WriteLine("おなじ"); b.Stop(); } Console.WriteLine($"{a.ElapsedMilliseconds}msec"); // 26msec Console.WriteLine($"{b.ElapsedMilliseconds}msec"); // 432msec }
したがって、可能な限りGuid型のまま持ち運んで必要ならToStringしたほうがシステムが効率的ですが、現場ではなぜかToStringしたstring型の値が持ち運ばれる事が多いようです。しかしながら比較を多用する場合、文字列の運搬について多少の考慮をした方がいいかもしれません。
以上です。