Encodingインスタンスの比較

.NETのEncodingはクラスです。

docs.microsoft.com

しかし、Encodingのインスタンス同士が比較できているような気がします。

そこで、簡単なコードで調べてみました。

// OS言語設定に基づくデフォルト言語コード
var encAnsi = Encoding.Default;

// Encoding.Cloneで別インスタンスを生成
var encAnsiClone = encAnsi.Clone();

// Windowsが日本語なら、コードページ932がデフォルト
var encSjis = Encoding.GetEncoding(932);

// Windowsの内部標準、UTF-16LE
var encUnicode = Encoding.Unicode;

// このUTF-8はBOMつき
var encUtf8 = Encoding.UTF8;

// UTF-8を文字列から取得。これもBOMつき
var encUtf8Str = Encoding.GetEncoding("utf-8");

// UTF8Encodingクラスを使い、BOMありUTF-8を生成
var encUtf8WithBom = new UTF8Encoding(true);

// UTF8Encodingクラスを使い、BOMなしUTF-8を生成
var encUtf8NoBom = new UTF8Encoding(false);

// UTF8Encodingクラスを使い、BOMなしUTF-8を生成(2つめ)
var encUtf8NoBom2 = new UTF8Encoding(false);

// UTF-16LEのBOMありをUnicodeEncodingから生成
var encUtf16WithBom = new UnicodeEncoding(false, true);

// UTF-16LEのBOMなしをUnicodeEncodingから生成
var encUtf16NoBom = new UnicodeEncoding(false, false);

var r1 = "Default == 932 : " + (encAnsi == encSjis);
var r2 = "Default == Default.clone : " + (encAnsi == encAnsiClone);
var r3 = "UTF8 == GetEncoding(utf-8) : " + (encUtf8 == encUtf8Str);
var r4 = "UTF8(withBOM) == UTF8(noBOM) : " + (encUtf8WithBom == encUtf8NoBom);
var r5 = "UTF8(noBOM) == UTF8(noBOM2) : " + (encUtf8NoBom == encUtf8NoBom2);
var r6 = "UTF8 == UTF8(withBOM) : " + (encUtf8 == encUtf8WithBom);
var r7 = "UTF8 == UTF8(noBOM) : " + (encUtf8 == encUtf8NoBom);
var r8 = "Unicode == Unicode(withBOM) : " + (encUnicode == encUtf16WithBom);
var r9 = "Unicode == Unicode(noBOM) : " + (encUnicode == encUtf16NoBom);
var r10 = "codepage : UTF8(withBOM) == UTF8(noBOM) : " + (encUtf8WithBom.CodePage == encUtf8NoBom.CodePage);
var r11 = "codepage : UTF8 == UTF8(noBOM) : " + (encUtf8.CodePage == encUtf8NoBom.CodePage);

var result = r1 + "\r\n" + r2 + "\r\n" + r3 + "\r\n" + r4 + "\r\n"
     + r5 + "\r\n" + r6 + "\r\n" + r7 + "\r\n" + r8 + "\r\n"
     + r9 + "\r\n" + r10 + "\r\n" + r11;
MessageBox.Show(result);

結果。

Default == 932 : True
Default == Default.clone : False
UTF8 == GetEncoding(utf-8) : True
UTF8(withBOM) == UTF8(noBOM) : False
UTF8(noBOM) == UTF8(noBOM2) : False
UTF8 == UTF8(withBOM) : False
UTF8 == UTF8(noBOM) : False
Unicode == Unicode(withBOM) : False
Unicode == Unicode(noBOM) : False
codepage : UTF8(withBOM) == UTF8(noBOM) : True
codepage : UTF8 == UTF8(noBOM) : True
  • falseになる例があるので、==は参照の比較
  • Encodingクラスから直接取得するものは、全て共有インスタンスへの参照
  • UnicodeEncodingやUTF8Encodingから生成すると別インスタンス
  • 文字コード(BOMの有無を問わず)の比較なら、とりあえずCodePageを比較するのが早そう

ちなみに、Encoding.GetEncoding()のRemarkに、次のようにあります。

docs.microsoft.com

GetEncoding returns a cached instance with default settings.

つまり、デフォルトでは共有インスタンスへの参照なのですね。