.NET 4を使用すると、コンパイラが以下のサンプルの最初のメソッド呼び出しを解決できないことが混乱しています。デフォルトのパラメータとジェネリックでのメソッド解決の問題
using System;
namespace MethodResolutionTest
{
class Program
{
static void Main(string[] args)
{
NonGeneric foo = null;
// ambiguous
foo.Ext1(x => new NonGeneric());
// resolves to first Ext1
foo.Ext1(x => new NonGeneric(), 1);
// resolves to first Ext2
foo.Ext2(x => new NonGeneric());
// resolves to first Ext2
foo.Ext2(x => new NonGeneric(), 1);
// resolves to second Ext2
foo.Ext2(x => "foo");
// resolves to second Ext2
foo.Ext2(x => "foo", 1);
// resolves to first Ext3
foo.Ext3(x => new NonGeneric());
// resolves to first Ext3
foo.Ext3(x => new NonGeneric(), 1);
// resolves to second Ext3
foo.Ext3(x => "foo");
// resolves to second Ext3
foo.Ext3(x => "foo", 1);
}
}
public class NonGeneric
{
}
public class Generic<T> : NonGeneric
{
}
public static class Extensions1
{
public static NonGeneric Ext1(this NonGeneric first, Func<NonGeneric, NonGeneric> getNext, int i = 0)
{
return null;
}
public static Generic<TNext> Ext1<TNext>(this NonGeneric first, Func<NonGeneric, TNext> getNext, int i = 0, string s = null)
{
return null;
}
}
// only difference between Extensions2 and Extensions1 is that the second overload no longer has a default string parameter
public static class Extensions2
{
public static NonGeneric Ext2(this NonGeneric first, Func<NonGeneric, NonGeneric> getNext, int i = 0)
{
return null;
}
public static Generic<TNext> Ext2<TNext>(this NonGeneric first, Func<NonGeneric, TNext> getNext, int i = 0)
{
return null;
}
}
// Extensions3 explicitly defines an overload that does not default the int parameter
public static class Extensions3
{
public static NonGeneric Ext3(this NonGeneric first, Func<NonGeneric, NonGeneric> getNext)
{
return Ext3(first, getNext, default(int));
}
public static NonGeneric Ext3(this NonGeneric first, Func<NonGeneric, NonGeneric> getNext, int i = 0)
{
return null;
}
public static Generic<TNext> Ext3<TNext>(this NonGeneric first, Func<NonGeneric, TNext> getNext, int i = 0)
{
return null;
}
}
}
誰もがこれにいくつかの光を当てることができますか?コンパイラの助けになるようにAPIを変更する以外の方法はありませんが(上記のExtensions3
)、もっと簡単で良い方法があれば、それを聞いてみたいと思います。
は、コンパイラは、 'Extensions2'と' Extensions3'シナリオの両方で正常に選択しますそれは簡単です。また、もし私がデフォルトの 'int'パラメータを必要としないなら、私は明らかにそれを最初に宣言しませんでした! –
しかし、オプションのパラメータを持つ2つの方法があるのはなぜですか?オプションのパラメータを省略すると、あいまいさがありますか?絶対に**両方の方法が必要な場合は、あなたの 'Extensions2'または' Extensions3'のいずれかのソリューションを使う必要があります。 – khellang
@khellang:C#言語仕様のセクションで、このような動作(オーバーロードの解決のあいまいさ)につながることがありますか? –