6

C#4.0コンソールプログラムの簡単なコードは次のとおりです。

using System.DirectoryServices.Protocols;
namespace OverloadTest
{
  class Program
  {
    static void Main(string[] args)
    {
      var request = new SearchRequest("", "", SearchScope.Base, null);
    }
  }
}

SearchRequestには3つのコンストラクターがあります。この例では、4つのパラメーターを取る2つだけが重要です。

これらの2つのコンストラクターの間では、1番目、3番目、および4番目のパラメーターに対して同じタイプおよび名前のパラメーターがあります。2番目のパラメーターのみが異なります:文字列ldapFilterXmlDocumentフィルター

上記のコードは、明らかに私にとって、2番目のパラメーターがstringldapFilterとして宣言されているコンストラクターを呼び出しています。

ただし、このコードが含まれているプロジェクトにSystem.XMLへの参照がない場合、コンパイルすると次のエラーが発生します
。タイプ'System.Xml.XmlDocument'は、参照されていないアセンブリで定義されています。アセンブリへの参照を追加する必要があります'System.Xml、Version = 4.0.0.0、Culture = neutral、PublicKeyToken =b77a5c561934e089'

明らかに、コンパイラは、使用するオーバーロードを評価できません。これは、間違ったオーバーロードに、宣言コンポーネントへの参照がないために理解されないタイプのパラメータが含まれているためです。確かに、コンパイラは私のコードに一致する「最良のメソッド」を見つける必要がありますが、2番目に渡されるパラメータは文字列であるため、コンパイラがコードをXmlDocumentオーバーロードに一致させることを気にする必要があるのはなぜですか?または、System.DirectoryServices.Protocols.SearchRequestがXmlDocumentタイプを(コンストラクターパラメータータイプとして)使用している場合。なぜコンパイラは、文字列が1つではないと判断し、正しいオーバーロードを選択できるようにするために、XmlDocumentが何であるかについて十分に理解していないのですか?

エラーなしでコンパイルする2つの回避策がすでにあります。

  1. プロジェクトにSystem.XMLへの参照を追加します。

  2. 次のように、2番目のパラメーターに名前を付けます(したがって、必要に応じて3番目と4番目も)。

    var request = new SearchRequest("", ldapFilter: "", searchScope: SearchScope.Base, attributeList: null);
    

    私の特定のケースでは、2つのオーバーロードの2番目のパラメーターがタイプだけでなく、名前(ldapFilterとfilter)も異なるため、これは機能します。

どちらの回避策も必要ない場合でも、それは素晴らしいことです。

4

1 に答える 1

3

暗黙の変換により、2番目のオーバーロードが引き続き適用される可能性があります。

この場合、完全に一致するため、常にが選択されると思います。stringただし、アルゴリズムはおそらくより一般的であり、他の過負荷が持つタイプを正確に知る必要があると判断した場合にエラーが発生します。

問題のある状況の例:

class A
{}

class B
{
    public static implicit operator B(A a)
    {
        return null;
    }
}

class C
{
    public static implicit operator C(A a)
    {
        return null;
    }
}

public static void M(B b)
{}

public static void M(C a)
{}

ここで、タイプBCは異なるアセンブリからのものです。ここで、を呼び出すとM(new A())、どのオーバーロードが選択されるかは、参照されているアセンブリによって異なります。このような振る舞いは望ましくないので、コンパイラは安全のために諦めます。

私が言ったように、あなたのサンプルは正確にはこのようではありませんが、コンパイラは同じルールに従っている可能性があります。

于 2012-02-16T01:48:29.467 に答える