En utilisant .NET 4, je suis confus par l'incapacité du compilateur à résoudre le premier appel de méthode dans l'exemple ci-dessous.Problème de résolution de méthode avec les paramètres par défaut et les génériques
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;
}
}
}
Quelqu'un peut-il nous éclairer à ce sujet? Je soupçonne que je n'ai pas vraiment un moyen d'aller de l'avant à part modifier mes API pour aider le compilateur (selon Extensions3
ci-dessus), mais s'il y a un moyen plus facile/meilleur, alors j'aimerais l'entendre.
Le compilateur choisit bien dans les deux '' Extensions2' et scénarios Extensions3', il est donc pas c'est simple. De plus, si je ne voulais pas le paramètre par défaut 'int', je ne l'aurais évidemment pas déclaré de cette façon en premier lieu! –
Mais pourquoi avez-vous deux méthodes avec des paramètres optionnels qui sont effectivement ambigus si les paramètres optionnels sont omis? Si vous avez absolument besoin des deux méthodes, vous devrez utiliser vos solutions Extensions2 ou Extensions3. – khellang
@khellang: pouvez-vous indiquer des sections de spécification de langage C# menant à un tel comportement (ambiguïté de résolution de surcharge)? –