Visual Studio によるエラーチェックは Web サイトプロジェクトと Web アプリケーションプロジェクトでは異なるという話を書きます。
自分の環境(Vista SP2 32-bit, Visual Studio 2010 Professional)で検証した結果をまとめると以下のようになりました:
-
Web サイトプロジェクト
設定したターゲットフレームワークに応じた言語バージョンに準拠(FW3.5 なら C# 3 または VB9.0、FW4 なら C# 4 または VB10.0)
-
Web アプリケーションプロジェクト
Visual Studio に採用された言語バージョンに準拠(VS2010 なら C# 4 または VB10.0)
これは、基本的にソースコードのままサーバーにデプロイしてサーバー側で動的にコンパイルを行う Web サイトプロジェクトと、Visual Studio で単一アセンブリ (.dll) にコンパイルして出来上がった .dll をサーバーにデプロイする Web アプリケーションプロジェクトとの違いからきていると思われます。
言語に C# を使って検証した場合の具体的な結果を以下に書いておきます。
(1) Web サイトプロジェクト
MSDN ライブラリの記事「What's New for Visual C#」によると、VS2010 の C# の言語バージョンは C# 4 で、Dynamic、名前付き引数と省略可能なパラメーター、ジェネリックの共変性/反変性が新機能としてサポートされたとのことです。
なので、名前付き引数を使ったメソッドをターゲットフレームワーク 3.5 の Web サイトプロジェクトのコードビハインドに実装して VS2010 によるエラーチェックがどうなるかを見てみました。
その結果が一番上の画像です。エディタレベルで VS2010 のエラーチェックに引っかかり、「3.0 C# 言語使用の一部ではないため、機能 '名前付き引数' を使用することはできません。」というエラーメッセージが出ています。
Visual Studio 上でビルドをかけると、[エラー一覧]にエラーが表示され(エディタレベルのエラーメッセージとは異なりますが)、ビルドに失敗します。もちろん実行はできません。
ブラウザのアドレスバーに直接 URL を入力して、ブラウザから問題のページを要求すると、サーバー側での動的コンパイルでコンパイルエラーとなり、以下の画像のサーバーエラーが応答として返ってきます。
これは web.config で、サーバー側で動的コンパイルに使うコンパイラが以下のように設定されており、これに従って C:\Windows\Microsoft.NET\Framework\v3.5 にあるコンパイラ csc.exe(自分の環境では製品バージョン 3.5.307129.1・・・名前付き引数はサポートしていない)が使用されるためです。
<system.codedom>
<compilers>
<compiler
language="c#;cs;csharp"
extension=".cs"
warningLevel="4"
type="Microsoft.CSharp.CSharpCodeProvider, System,
Version=2.0.0.0,
Culture=neutral,
PublicKeyToken=b77a5c561934e089">
<providerOption name="CompilerVersion" value="v3.5"/>
<providerOption name="WarnAsError" value="false"/>
</compiler>
</compilers>
</system.codedom>
同じコードをターゲットフレームワークが 4 の Web サイトプロジェクトに実装すれば、当然ながらエラーメッセージ等は一切出ず、ビルドも実行も問題ありません。
(2) Web アプリケーションプロジェクト
上記 (1) と同じコードをターゲットフレームワーク 3.5 の Web サイトプロジェクトのコードビハインドに実装してみます。動的コンパイルに使うコンパイラの設定(web.config の system.codedom 要素の設定)は上の (1) Web サイトプロジェクトの場合と同じです。
結果、上記 (1) Web サイトプロジェクトの時のようなエディタ上のエラーは出ません。ビルドも通りますし、実行上も問題ありません。
ということは、ターゲットフレームワークの設定には関係なく、VS2010 に採用された言語バージョン C# 4 をベースに VS2010 のエディタ上でエラーチェックが行われ、ビルドも言語バージョン C# 4 のコンパイラで行われているということになります。
では、動的コンパイルが行われる部分はどうでしょうか?(Web アプリケーションプロジェクトでも .aspx ファイルや App_Code のソースなどはデフォルトではサーバー側で動的コンパイルが行われます)
まず、.aspx ファイルに以下のようなコードブロック(<% から %> までのコード)を実装してみます。
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server"></asp:Label>
<br />
<% =CalculateBMI(height: 64, weight: 123) %>
</form>
</body>
そうすると、エディタレベルで一番上と同様なエラーが表示されます。ただし、コードブロックの部分は Visual Studio ではコンパイルされないためか、ビルドは通ります。実行したりブラウザから要求をかけた場合は動的コンパイルが行われ、コードブロックの部分でコンパイルエラーとなり、上の 2 つ目の画像と同様なサーバーエラーとなります。
次に、App_Code に以下のようなクラスファイルを実装してみます。クラスファイル Class1.cs のビルドアクションは「コンテンツ」「コンパイル」いずれの場合もエディタレベルではエラーは表示されません。ビルドも通ります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Framework35CSharp.App_Code
{
public class Class1
{
public int CalculateBMI(int weight, int height)
{
return (weight * 703) / (height * height);
}
public string BMI64x123()
{
return CalculateBMI(height: 64, weight: 123).ToString();
}
}
}
2 重コンパイルの問題を避けるためにクラスファイル Class1.cs のビルドアクションは「コンテンツ」として実行してみます。するとサーバー側で動的コンパイルが行われ、名前付き引数を使っているところでコンパイルエラーとなり、上の 2 つ目の画像と同様なサーバーエラーとなります。ブラウザから要求をかけた場合も同様にサーバーエラーが返ってきます。(ビルドアクションを「コンパイル」にしても同様に動的コンパイルでエラーになります)
元は MSDN Forum の「ASPNET WEBサイト(VB)で、yieldが使用できない」という表題のスレッドでの話で、VB.NET の場合の検証結果はそちらに書きましたが若干様子が異なります。
また、そのフォーラムに VS2012 / 2013 では Web アプリケーションプロジェクトの App_Code フォルダでもエディタによるエラーチェックは働くという話があります。Visual Studio のバージョンによって異なるのかもしれません。(自分は検証できる環境を持ってないので未確認ですが)