新人研修で課題として作っていたサンプルでたまたま見つけた挙動、というか仕様。忘れないようにメモしておきます。
BOM付きUTF-8ファイルをSJIS指定のStreamReaderで開く
結論:開けます。下記のように、GetEncodingでShift-JISを指定したStreamReaderであっても、BOM(Byte Order Mark)付きのUTF-8ファイルを開くと、文字化け無しに開くことができます。
StreamReader reader = new StreamReader("CsvFile/Sample.csv", Encoding.GetEncoding("sjis"));
ファイルがBOM無しのUTF-8であればダメです。綺麗に文字化けしてしまいます。
StreamReaderの第3引数が自動判別の原因
上記の例ではStreamReaderのコンストラクターに2つの引数を指定していますが、MS.のドキュメントを見てみるとコンストラクターが3つのオーバーロードが用意されており、その説明は下記のようになっています。
StreamReader(String, Encoding, Boolean)
文字エンコーディングとバイト順マーク検出オプションを設定して、指定したファイル名用の StreamReader クラスの新しいインスタンスを初期化します。
第3引数は「バイト順マーク検出オプション」、バイト順マークとはBOMのことで、第3引数にTrueを指定すれば、BOMが検出されるとUTF-8であると自動判定するようです。で、この第3引数を省略するとTrueになるようですね。明確にここにFalseを指定すると、Shift-JIS以外のファイルでは文字化けを起こします。