5

共通の拡張メソッドを含む別のアセンブリを作成しました。拡張メソッドはSystem.Web.dll(およびその他) のクラスを使用します。

次に、拡張メソッドを含むアセンブリを参照する新しいプロジェクト (コンソール アプリケーション) を作成するときに、アセンブリ内のクラスを拡張する拡張メソッドを使用しない場合は、新しいプロジェクトへUtilities.dllの参照を追加する必要はありません(たとえば)。System.Web.dllSystem.Web.dllSystem.Web.UI.Control

拡張メソッドの 1 つがジェネリック メソッドになる場合、すべてが期待どおりに機能し続けます。しかし、アセンブリ内のクラスに制約するジェネリック メソッドに制約を追加するとすぐにSystem.Web.dll、コンパイラはSystem.Web.dll、新しいプロジェクトがまだそのアセンブリ内で何も使用していない場合でも、新しいプロジェクト (コンソール アプリケーション) への参照が必要であると不平を言います。 .

言い換えれば、ジェネリックメソッドに制約がない限り、すべてがコンパイルされますが、制約を追加するとすぐにコンパイラが文句を言います。

私の拡張メソッド アセンブルの例 (ライブラリとしてコンパイル)Utilities.dll):

public static class StringExtensions
{
    public static bool IsNullOrEmpty(this string value)
    {
        return string.IsNullOrEmpty(value);
    }
}

public static class ControlExtensions
{
    // If I remove the where clause it compiles
    public static T FildChild<T>(this Control parent, string id)
        where T : Control
    {
        throw new NotImplementedException();
    }
}

And here is a new console application that won't compile (unless I also add a reference to System.Web.dll):

    static void Main(string[] args)
    {
        bool isEmpty = "Hello World!".IsNullOrEmpty();

        Console.ReadLine();
    }


Update: As Marc pointed out (below) puting the offending method in a separate namespace fixes the problem.

But the question still remains why is the constraint a problem while the type Control was already used as a parameter to the method. and why is the namespace the solution when I already use the using上のディレクティブ。

4

2 に答える 2

5

はい、そうです!コンパイルするには、パブリック/保護された API のすべてを解決できる必要があります。そうしないと、制約を適用できません。拡張メソッドがメソッドの候補かどうかを確認するには、型を認識する必要があると思います。

「Web」を含む子名前空間に拡張メソッドを配置してみてください。少なくとも、通常のコードには影響しません。を確認しましたが、これで問題は解決しました。拡張メソッドの名前空間を分離して、呼び出し元がスコープ内にある必要があるタイミングを制御できるようにすることをお勧めします。

実行するには、内部で使用されているが API で公開されていないものを解決できる必要もあります。これは標準的な動作です。

于 2008-12-18T13:10:48.623 に答える
1

@Marc がその理由を教えてくれます。Web クラスを参照するものはすべて、さらに別のアセンブリに分割することをお勧めします。Com.Company.Extensions に加えて、Com.Company.Extensions.Web などです。次に、Web プロジェクトに両方を含め、他のプロジェクトに非 Web 拡張機能のみを含めることができます。

于 2008-12-18T13:17:05.757 に答える