4

IEnumerable<T>メソッドのオーバーロードを広範囲に使用したり、から派生した型のオブジェクトをシリアル化したりするシリアライザーを作成しIDictionary<K,V>ています。

dynamicまた、キーワードを使用して、シリアル化するオブジェクトの実行時の型に基づいて CLR が正しいオーバーロードを選択できるようにするつもりです。

このコード スニペットを見てください。

void Serialize<TKey, TValue>(IDictionary<TKey, TValue> dictionary)
{
  Console.WriteLine("IDictionary<TKey, TValue>");
}

void Serialize<TKey, TValue>(IEnumerable<KeyValuePair<TKey, TValue>> items)
{
  Console.WriteLine("IEnumerable<KeyValuePair<TKey, TValue>>");
}

void Serialize<T>(IEnumerable<T> items)
{
  Console.WriteLine("IEnumerable<T>");
}

そして、私はこれをしたい:

void CallSerialize(object obj)
{
   Serialize(obj as dynamic); //let the CLR resolve it at runtime.
}

のランタイム タイプに基づいてobj、正しいオーバーロードが呼び出されるようになりました。例えば、

//Test code
CallSerialize(new List<int>()); //prints IEnumerable<T>

この場合、3 番目のオーバーロードが呼び出されます。論理的根拠は非常に単純です。これは実行可能なオプションにすぎません。

ただし、これを行うと:

CallSerialize(new Dictionary<int,int>()); //prints IDictionary<TKey, TValue>

最初のオーバーロードを呼び出します。私はこれを正確に理解していません。3 つのオーバーロードすべてが実行可能なオプションであるのに、最初のオーバーロードに解決されるのはなぜですか?

実際、最初のオーバーロードを削除すると 2 番目のオーバーロードが呼び出され、1 番目と 2 番目のオーバーロードを削除すると 3 番目のオーバーロードが呼び出されます。

メソッドのオーバーロードを解決する際の優先規則は何ですか?

4

1 に答える 1

6

メソッドのオーバーロードを解決するためのルールは、最も具体的な型が一致するメソッド ヘッダーを選択しようとします。ここでは、オーバーロードの解決について詳しく読むことができます。ここでは、あなたのケースだと思います。

MSDN から:

引数の型のセット {A1, A2, ..., AN} を持つ引数リスト A と、パラメーターの型 {P1, P2, ..., PN} と {Q1, Q2, ..., QN} の場合、MP は MQ よりも優れた関数メンバーとして定義されます。

  • 各引数について、AX から PX への暗黙的な変換は、AX から QX への暗黙的な変換より悪くはありません。

  • 少なくとも 1 つの引数について、AX から PX への変換は >AX から QX への変換よりも優れています。

この評価を実行するときに、MP または MQ が展開された形式で適用できる場合、PX または QX はパラメーター リストの展開された形式のパラメーターを参照します。

于 2012-11-20T14:07:28.953 に答える