Mit .NET 4 bin ich verwirrt durch die Unfähigkeit des Compilers, den ersten Methodenaufruf in dem Beispiel unten aufzulösen.Problem mit der Methodenauflösung mit Standardparametern und Generics
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;
}
}
}
Kann jemand etwas Licht darauf werfen? Ich vermute, dass ich hier wirklich keinen Weg nach vorne gefunden habe, außer meine APIs zu modifizieren, um dem Compiler zu helfen (wie oben unter Extensions3
), aber wenn es einen einfacheren/besseren Weg gibt, dann würde ich es gerne hören.
Der Compiler in feinen wählt beiden 'Extensions2' und' Extensions3' Szenarien, so ist es nicht so einfach. Wenn ich nicht den Standardparameter "int" haben wollte, hätte ich das natürlich auch nicht so erklärt! –
Aber warum haben Sie zwei Methoden mit optionalen Parametern, die mehrdeutig sind, wenn die optionalen Parameter weggelassen werden? Wenn Sie beide Methoden absolut ** brauchen, müssen Sie entweder Ihre 'Extensions2' oder' Extensions3' Lösungen verwenden. – khellang
@khellang: Können Sie auf C# -Sprachspezifikationsabschnitte hinweisen, die zu einem solchen Verhalten führen (Mehrdeutigkeit der Überladungsauflösung)? –