9
public enum EnumTest
{
    EnumEntry
}

public class TestClass
{
    public string FunctionMember(string s, EnumTest t = EnumTest.EnumEntry)
    {
        return "Normal";
    }

    public string FunctionMember<T>(T t)
    {
        return "Generic";
    }
}

class Program
{
    static void Main(string[] args)
    {
        TestClass t = new TestClass();

        Console.WriteLine(t.FunctionMember("a"));
    }
}

これは「ジェネリック」を印刷します。削除, EnumTest t = EnumTest.EnumEntryすると「通常」と印刷されます。

それでも、標準はかなり明確に見えます。14.4.2.2より優れた機能メンバーから、最初に適用される識別子は次のとおりです。

  • MPとMQの一方が非ジェネリックであり、もう一方がジェネリックである場合は、非ジェネリックの方が適しています。

何かまたはコンパイラのバグがありませんか?

4

3 に答える 3

8

あなたは何かが欠けています。そして、それは次のとおりです。

1 つのパラメーターを使用してメソッドを呼び出します。パラメーターを 1 つ持つメソッドは、ジェネリック メソッドのみです。それで選ばれた方です。

一致するメソッドが見つからない場合にのみ、オプションのパラメーターを持つ他のメソッドを調べます。

参考文献:

  1. C# 4.0 仕様、21.4 の最後の段落:

    タイ ブレーカー ルールとして、明示的に指定されたすべての引数が、明示的な引数の代わりに既定値が指定されたものよりも優れている関数メンバー。

  2. MSDN、見出し「過負荷の解決」、最後の箇条書き:

    2 つの候補が同等に優れていると判断された場合、呼び出しで引数が省略されたオプションのパラメーターを持たない候補が優先されます。これは、より少ないパラメーターを持つ候補のオーバーロード解決における一般的な好みの結果です。

  3. C# 言語仕様、章「7.5.3.2 より良い関数メンバー」:

    各候補関数メンバーのパラメーター リストは、次の方法で作成されます。

    • 関数メンバーが展開された形式でのみ適用可能であった場合、展開された形式が使用されます。
    • 対応する引数のないオプションのパラメーターは、パラメーター リストから削除されます。

    次のように続きます。

    一連の引数式 { E 1 , E 2 , ..., E N } を持つ引数リスト A と、パラメーター型 { P 1 , P 2 , ..., P N }を持つ 2 つの適用可能な関数メンバー MP および MQ があるとします。そして { Q 1 , Q 2 , ..., Q N } [...]

    この時点で、オプションのパラメーターを持つメソッドは既にゲームから外れています。Nは 1 ですが、そのメソッドには 2 つのパラメーターがあります。

于 2013-02-15T13:08:34.493 に答える
3

ドキュメントによると:

2つの候補が同等に良好であると判断された場合、呼び出しで引数が省略されたオプションのパラメーターを持たない候補が優先されます。これは、パラメータが少ない候補者の過負荷解決における一般的な好みの結果です。

つまり、オプションの引数を指定しない方法が優先されます。

于 2013-02-15T13:13:00.983 に答える
1

メソッド パラメータのデフォルト値により、オーバーロードの解決が拡張されました。

概念的には、v4 より前のメソッド オーバーロードの解決が実行されます。一致が見つかった場合、その一致が使用されます。(概念的には、これはどのように機能するかの説明ではなく、どのように考えることができるかという理由からです)

あなたの場合、ジェネリックメソッドである正確に1つの一致が見つかります

一致が見つからない場合は、部分一致があり、デフォルト値で一致を完了できるメソッドを探します。あなたの場合、あなたの none generice メソッドはこの実行で見つかりますが、すでに一致が見つかっているため、解決策はこれまでにありません。

2 番目のパラメーターを削除すると、ジェネリックと非ジェネリックが一致する状況になります。そして、あなたが引用したルールは、非ジェネリックを選択する際に適用されます。

全体として、利用可能な最も具体的な方法が選択されるというのが、一般的な経験則です。

一致する非ジェネリック メソッドは、型が変化しないため、ジェネリックよりも具体的です。2 つのメソッドが使用可能であるが、一方が IFoo の引数を取り、もう一方が Foo を取り (IFoo を実装する)、後者は、Foo オブジェクトを引数として渡すときに選択されます。これは完全に一致するためです。より具体的に

于 2013-02-15T13:15:39.833 に答える