4

対応する VS dev チケットがあります https://connect.microsoft.com/VisualStudio/feedback/details/817276/error-cs0012-the-type-is-defined-in-an-assembly-that-is-not-referenced -使用されていない拡張メソッドに対して発行された

私は2つの拡張方法を持っています:

public static class ExtensionMethods
{
    public static string GetClientIpAddress(this HttpRequestBase request)
    {
        // ...
    }

    public static string GetClientIpAddress(this HttpRequestMessage request)
    {
        // ...
    }
}

クラスHttpRequestMessageSystem.Net.HttpアセンブリにHttpRequestBaseあり、System.Web(つまり、異なるアセンブリに) あります。クラスExtensionMethodsProjectAとしましょう。

このプロジェクトはうまくコンパイルされ、問題はありません。

次に、次のようにGetClientIpAddress(this HttpRequestBase request)、別のプロジェクト (たとえばProjectB )の最初のメソッドを使用します。

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    base.OnActionExecuting(filterContext);
    var sessionContext = DependencyResolver.Current.GetService<ISessionContext>();

    // Call to GetClientIpAddress
    sessionContext.ClientIpAddress =
        filterContext.HttpContext.Request.GetClientIpAddress();
}

ProjectB には既に への参照がありますがSystem.Web、コンパイルしようとすると、コンパイル エラーが発生します。

タイプ ' System.Net.Http.HttpRequestMessage' は、参照されていないアセンブリで定義されています。アセンブリ ' ' への参照を追加する必要がありますSystem.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

私が理解できないのは、なぜ への参照を追加する必要があるのか​​ということSystem.Net.Httpです。

コンパイラが 2 番目の方法を使用しようとしているようで、GetClientIpAddress(this HttpRequestMessage request)これによりアセンブリへの参照が失われます。これはバグですか?

最初のメソッドの名前を変更すると (つまり、オーバーロードを取り除くと)、すべてがうまくコンパイルされます。

4

2 に答える 2

7

C# 5.0 仕様、セクション 7.5.3 から:

適用可能な候補関数メンバーのセットが与えられると、そのセット内の最適な関数メンバーが特定されます。セットに関数メンバーが 1 つしか含まれていない場合、その関数メンバーが最適な関数メンバーです。それ以外の場合、§7.5.3.2 の規則を使用して各関数メンバーが他のすべての関数メンバーと比較される場合、最良の関数メンバーは、指定された引数リストに関して他のすべての関数メンバーよりも優れている 1 つの関数メンバーです。

セクション 7.5.3.2:

引数式のセット { E 1 , E 2 , ..., E N } を持つ引数リスト A と、パラメーター型 { P 1 , P 2 , ..., Pを持つ2 つの適用可能な関数メンバー M Pおよび M Qが与えられた場合N } および { Q 1 , Q 2 , ..., Q N } の場合、M Pは、次の場合に M Qよりも優れた関数メンバーであると定義されます。

• 各引数について、E Xから Q Xへの暗黙的な変換は、E Xから P Xへの暗黙的な変換よりも優れていません。

• 少なくとも 1 つの引数について、EX からP X への変換は E Xから Q Xへの変換よりも優れています。

「引数の型がパラメーターの型と正確に一致する場合は、それを選択する」という規則はありません。したがって、コンパイラーは、上記の規則を評価できるようにするために、すべてのパラメーターの型に関する完全な型情報を必要とします。

への参照を追加せずに問題を解決するには、System.Net.Http? 答えはすでに見つかりました。別のメソッド名を使用してください。前に引用した 7.5.3 の部分のおかげで、成功することができます。

セットに関数メンバーが 1 つしか含まれていない場合、その関数メンバーが最適な関数メンバーです。

于 2013-07-09T13:03:28.280 に答える
0

また、拡張メソッドを使用せずに簡単なテストを行ったところ、同じ効果が得られました。Damien_The_Unbeliever が言ったように、この問題はメソッドのオーバーロードのみに関連しています。

于 2013-07-09T16:00:02.427 に答える