Visual Studio 2015 と .NET Framework 4.6.1 の csc (C#コンパイラー) の違いについて

# はじめに

　最近、 Visual Studio 2015 をインストールし、Visual Studio 2012 から移行を始めました。
.NET Framework の 4系も それまで利用している 4.5.2 から 4.6.1 に更新されました。(リプレース更新なので置き換わります）

今回ビルドしたい対象プロジェクトは、C#のため、C#コンパイラーである csc.exe の違いについて調べました。

# 結論
* .NET Framework 4.6.1 が提供するコンパイラ(csc) は C# 5.0 である。
* Visual Studio 2015 が提供するコンパイラ(csc) は C# 6.0 である。


# 調査内容
## csc.exe がいる場所

* .NET Framework 内にいるcsc.exe
`"C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe"`

* VS2015 内にいるcsc.exe
`"C:\Program Files (x86)\MSBuild\14.0\bin\csc.exe"`



## .NET Framework 内にいるcsc.exe の場合
まずはヘルプを表示してみます。

```
>C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /?
Microsoft (R) Visual C# Compiler version 4.6.1055.0
for C# 5
Copyright (C) Microsoft Corporation. All rights reserved.

This compiler is provided as part of the Microsoft (R) .NET Framework, but only
supports language versions up to C# 5, which is no longer the latest version. Fo
r compilers that support newer versions of the C# programming language, see http
://go.microsoft.com/fwlink/?LinkID=533240

                        Visual C# Compiler のオプション

                        - 出力ファイル -
/out:<ファイル>                出力ファイル名を指定します (既定: メイン
                               クラスかファースト
                               ファイルを伴うファイルのベース名)。
/target:exe                    コンソール アプリケーションをビルドします
                               (既定)。 (短い形式: /t:exe)
/target:winexe                 Windows 実行可能ファイルをビルドします。
                               (短い形式: /t:winexe)
/target:library                ライブラリをビルドします。 (短い形式: /t:library)
/target:module                 別のアセンブリに追加できるモジュールをビルドしま
                               す。 (短い形式: /t:module)
/target:appcontainerexe        Appcontainer 実行可能ファイルのビルド (短い形式:
                               /t:appcontainerexe)
/target:winmdobj               WinMDExp で使用される Windows
                               ランタイムの中間ファイルのビルド (短い形式:
                               /t:winmdobj)
/doc:<ファイル>                生成する XML ドキュメント ファイル
/platform:<文字列>             このコードが実行されるプラットフォームの制限:
                               x86、Itanium、x64、arm、anycpu32bitpreferred、ま
                               たは anycpu。既定は anycpu です。

                        - 入力ファイル -
/recurse:<ワイルドカード>      ワイルドカードの指定に従い、現在のディレクトリと
                               サブディレクトリ内のすべてのファイルをインクルー
                               ドします。
/reference:<エイリアス>=<ファイル>
                               指定されたエイリアスを使用して、指定されたアセン
                               ブリ ファイルからメタベースを参照する (短い形式:
                               /r)
/reference:<ファイル リスト>   指定されたアセンブリ
                               ファイルからメタベースを参照する (短い形式: /r)
/addmodule:<ファイル リスト>   指定されたモジュールをこのアセンブリにリンクする
/link:<ファイル リスト>        指定された相互運用機能アセンブリ
                               ファイルからメタデータを埋め込みます (短い形式:
                               /l)

                        - リソース -
/win32res:<ファイル>           Win32 リソース ファイルを指定します (.res)。
/win32icon:<ファイル>          出力にこのアイコンを使用します。
/win32manifest:<ファイル>      Win32 マニフェスト ファイル (.xml)
                               を指定してください。
/nowin32manifest               既定の Win32 マニフェストを含めません。
/resource:<リソース情報>       指定したリソースを埋め込みます。 (短い形式: /res)
/linkresource:<リソース情報>   このアセンブリに指定されたリソースをリンクします
                               。 (短い形式: /linkres)
                               リソース情報の形式は <ファイル>[,<文字列名>
                                                             [,public|private]]
                               です。

                        - コード生成 -
/debug[+|-]                    デバッグ情報を生成する
/debug:{full|pdbonly}          デバッグの種類を指定します (既定値は full
                               で、実行中のプログラムにデバッガーを付加すること
                               ができます)。
/optimize[+|-]                 最適化を有効にする (短い形式: /o)

                        - エラーと警告 -
/warnaserror[+|-]              すべての警告をエラーとして報告する
/warnaserror[+|-]:<警告リスト> 指定した警告をエラーとして報告する
/warn:<n>                      警告レベル (0-4) を設定する (短い形式: /w)
/nowarn:<警告リスト>           指定の警告メッセージを無効にする

                        - 言語 -
/checked[+|-]                  オーバーフロー チェックの生成
/unsafe[+|-]                   アンセーフ コードの許可
/define:<シンボル リスト>      条件付きコンパイル シンボルを定義する (短い形式:
                               /d)
/langversion:<文字列>          言語バージョン モードの指定:
                               ISO-1、ISO-2、3、4、5、または Default

                        - セキュリティ -
/delaysign[+|-]                厳密な名前のキーのパブリックな部分のみを使ってア
                               センブリを遅延署名します。
/keyfile:<ファイル>            厳密な名前のキー ファイルを指定します。
/keycontainer:<文字列>         厳密な名前のキー コンテナーを指定します。
/highentropyva[+|-]            高エントロピ ASLR の有効化

                        - その他 -
@<ファイル>                    応答ファイルを読み取り、オプションを追加します。
/help                          この使用法のメッセージを表示します。 (短い形式:
                               /?)
/nologo                        コンパイル時の著作権メッセージを表示しません。
/noconfig                      CSC.RSP ファイルを自動的に含めません。

                        - 詳細 -
/baseaddress:<アドレス>        ビルドするライブラリのベース アドレスです。
/bugreport:<ファイル>          'バグ報告' ファイルを作成します
/codepage:<n>                  ソース
                               ファイルを開くときに使用するコードページを指定し
                               ます。
/utf8output                    UTF-8
                               エンコードでコンパイラのメッセージを出力する
/main:<型>                     エントリ ポイントを含む型を指定します
                               (他のエントリ ポイントはすべて無視します)。
                               (短い形式: /m)
/fullpaths                     コンパイラは絶対パスを生成します。
/filealign:<n>                 出力ファイル
                               セクションで使用する配置を指定します。
/pdb:<ファイル>                デバッグ情報ファイル名を指定します (既定: .pdb
                               拡張子の付いた出力ファイル名)
/errorendlocation              各エラーの終了位置の出力行と出力列
/preferreduilang               出力用の言語名を指定します。
/nostdlib[+|-]                 標準ライブラリ (mscorlib.dll) を参照しない
/subsystemversion:<文字列>     このアセンブリのサブシステム
                               バージョンを指定してください
/lib:<ファイル リスト>         参照を検索する追加のディレクトリを指定します。
/errorreport:<文字列>          内部コンパイラ エラーの処理方法を指定します:
                               prompt、send、queue、または none です。既定値は
                               queue です。
/appconfig:<ファイル>          アセンブリ
                               バインディング設定を含むアプリケーション構成ファ
                               イルを指定してください
/moduleassemblyname:<文字列>   このモジュールが一部となるアセンブリ名です
```



## VS2015 の csc.exe 
```
Microsoft (R) Visual C# Compiler バージョン 1.1.0.51204
Copyright (C) Microsoft Corporation. All rights reserved.

 
                              Visual C# コンパイラのオプション

                        - 出力ファイル -
 /out:<file>                   出力ファイル名を指定します (既定: メイン クラスの 
                               ファイルまたは最初のファイルのベース名)
 /target:exe                   コンソール実行可能ファイルをビルドします (既定) (短い 
                               形式: /t:exe)
 /target:winexe                Windows 実行可能ファイルをビルドします (短い形式: 
                               /t:winexe)
 /target:library               ライブラリをビルドします (短い形式: /t:library)
 /target:module                別のアセンブリに追加できるモジュールをビルド 
                               します (短い形式: /t:module)
 /target:appcontainerexe       Appcontainer 実行可能ファイルをビルドします (短い形式: 
                               /t:appcontainerexe)
 /target:winmdobj              WinMDExp で使用される 
                               Windows ランタイムの中間ファイルをビルドします (短い形式: /t:winmdobj)
 /doc:<file>                   生成する XML ドキュメント ファイル
 /platform:<string>            このコードを実行できるプラットフォームを x86、
                               Itanium、x64、arm、anycpu32bitpreferred、
                               anycpu に制限します。 既定は anycpu です。

                        - 入力ファイル -
 /recurse:<wildcard>           ワイルドカードの指定に従い、現行ディレクトリおよび 
                               サブディレクトリ内のすべてのファイルを 
                               インクルードします
 /reference:<alias>=<file>     指定されたエイリアスを使用して、指定された 
                               アセンブリ ファイルのメタデータを参照します (短い形式: /r)
 /reference:<file list>        指定されたアセンブリ ファイルのメタデータを参照 
                               します (短い形式: /r)
 /addmodule:<file list>        指定されたモジュールをこのアセンブリにリンクします
 /link:<file list>             指定された相互運用アセンブリ ファイルのメタデータを 
                               埋め込みます (短い形式: /l)
 /analyzer:<file list>         このアセンブリからアナライザーを実行します
                               (短い形式: /a)
 /additionalfile:<file list>   コード生成には直接影響しないものの、
                               アナライザーがエラーまたは警告を
                               生成するときに使用する可能性のある追加ファイル。

                        - リソース -
 /win32res:<file>              Win32 リソース ファイル (.res) を指定します
 /win32icon:<file>             出力にこのアイコンを使用します
 /win32manifest:<file>         Win32 マニフェスト ファイル (.xml) を指定します
 /nowin32manifest              既定の Win32 マニフェストはインクルードしません
 /resource:<resinfo>           指定されたリソースを埋め込みます (短い形式: /res)
 /linkresource:<resinfo>       指定されたリソースをこのアセンブリにリンクします 
                               (短い形式: /linkres) ここで resinfo の形式 
                               は <file>[,<string name>[,public|private]] です

                        - コード生成 -
 /debug[+|-]                   デバッグ情報を生成します
 /debug:{full|pdbonly|portable}
                               デバッグの種類を指定します ('full' が既定で、
                               実行中のプログラムへのデバッガーの接続を 
                               有効にします。'portable' はクロスプラットフォーム形式です)
 /optimize[+|-]                最適化を有効にします (短い形式: /o)
 /deterministic                決定論的アセンブリを作成します
                               (モジュール バージョン GUID やタイムスタンプなど)

                        - エラーと警告 -
 /warnaserror[+|-]             すべての警告をエラーとして報告します
 /warnaserror[+|-]:<warn list> 特定の警告をエラーとして報告します
 /warn:<n>                     警告レベル (0-4) を設定します (短い形式: /w)
 /nowarn:<warn list>           特定の警告メッセージを無効にします
 /ruleset:<file>               特定の診断を無効にするルールセット ファイルを
                               指定します。
 /errorlog:<file>              すべてのコンパイラとアナライザーの診断をログに記録するための
                               ファイルを指定します。
 /reportanalyzer               追加のアナライザー情報を報告します
                               (実行時間など)。
 
                        - 言語 -
 /checked[+|-]                 オーバーフロー検査を生成します
 /unsafe[+|-]                  '安全でない' コードを許可します
 /define:<symbol list>         条件付きコンパイル シンボルを定義します (短い 
                               形式: /d)
 /langversion:<string>         言語バージョン モードを指定します: ISO-1、ISO-2、3、
                               4、5、6、既定

                        - セキュリティ -
 /delaysign[+|-]               アセンブリの遅延署名に厳密な名前キーの 
                               公開された部分のみを使用します
 /keyfile:<file>               厳密な名前キーのファイルを指定します
 /keycontainer:<string>        厳密な名前キーのコンテナーを指定します
 /highentropyva[+|-]           高エントロピ ASLR を有効化します

                        - その他 -
 @<file>                       応答ファイルを読み込み、オプションを追加します
 /help                         使用法に関するメッセージを表示します (短い形式: /?)
 /nologo                       コンパイル時の著作権メッセージを表示しません
 /noconfig                     CSC.RSP ファイルを自動的に含めません
 /parallel[+|-]                ビルドを並列処理します。 

                        - 詳細 -
 /baseaddress:<address>        ビルドするライブラリのベース アドレス
 /bugreport:<file>             'バグ報告' ファイルを作成します
 /checksumalgorithm:<alg>      PDB に格納されているソース ファイルのチェックサム 
                               を計算するアルゴリズムを指定します。サポートされる値:
                               SHA1 (既定) や SHA256。
 /codepage:<n>                 ソース ファイルを開くときに使用するコード ページを 
                               指定します
 /utf8output                   コンパイラ メッセージを UTF-8 エンコードで出力します
 /main:<type>                  エントリ ポイントを含む型を指定します 
                               (他のエントリ ポイントはすべて無視します)。 (短い 
                               形式: /m)
 /fullpaths                    コンパイラは絶対パスを生成します
 /filealign:<n>                出力ファイル セクションで使用する配置を指定 
                               します
 /pathmap:<K1>=<V1>,<K2>=<V2>,...
                               コンパイラが出力するソース パス名のマッピングを
                               指定します。
 /pdb:<file>                   デバッグ情報ファイル名を指定します (既定: 
                               .pdb 拡張子の付いた出力ファイル名)
 /errorendlocation             各エラーの終了位置の出力行と 
                               出力列
 /preferreduilang              出力用の言語名を指定します。
 /nostdlib[+|-]                標準ライブラリ (mscorlib.dll) は参照しません
 /subsystemversion:<string>    このアセンブリのサブシステム バージョンを指定します\r
 /lib:<file list>              参照を検索する追加ディレクトリを指定 
                               します
 /errorreport:<string>         内部コンパイラ エラーの処理方法を指定します: 
                               prompt、send、queue、none です。既定値は 
                               queue です。
 /appconfig:<file>             アセンブリ バインディング設定を含む 
                               アプリケーション構成ファイルを指定します
 /moduleassemblyname:<string>  このモジュールが一部となるアセンブリ名 
                               です
 /modulename:<string>          ソース モジュールの名前を指定します


```
まず、csc.exe のバージョンが異なるみたいですね。

また、.NET 4.6.2のcscのヘルプに下記記載があります。
> This compiler is provided as part of the Microsoft .NET Framework, but only supports language versions up to C# 5, which is no longer the latest version. For compilers that support newer versions of the C# programming language, see http://go.microsoft.com/fwlink/?LinkID=533240

抄訳すると
> このコンパイラは、Microsoft .NET Frameworkの一部として提供されますが、C# 5までのバージョンをサポートしています。これはもはや最新バージョンをサポートしていません。C＃プログラミング言語の新しいバージョンをサポートするコンパイラはこちら http://go.microsoft.com/fwlink/?LinkID=533240

上記リンクを踏むと、 Roslyn の　GitHub のページに飛ばされました。Roslyn で検索して、http://www.buildinsider.net/enterprise/roslyn/01 等を読んだところ、VS2015 の場合、C# 6.0 をサポートしていることがわかりました。

.NET 4.6.1 の csc は以下の挙動でした。

* C# 6.0 のコードは、ビルドエラー
* C# 5.0 のコードは、では、[foreach の仕様変更](http://ufcpp.net/study/csharp/ap_ver5.html) があり、C# 5.0 の挙動になっていました。

## 結論
* .NET Framework 4.6.1 が提供するコンパイラ(csc) は C# 5.0 である。
* Visual Studio 2015 が提供するコンパイラ(csc) は C# 6.0 である。