private static void TestAmbiguousGenerics()
{
var string1 = "Hello".Foo(s => s + " world"); // works
int? n = 123;
var string2 = n.Foo(x => (x + 1).ToString()); // compiler error
Console.WriteLine("{0} {1}".Fmt(string1, string2));
}
public static string Foo<T>(this T obj, Func<T, string> func) where T : class
{
return obj == null ? "" : func(obj);
}
public static string Foo<T>(this T? str, Func<T, string> func) where T : struct
{
return str == null ? "" : func(str.Value);
}
The compiler can't tell whether I'm calling the first overload of Foo<T>
where T
is Nullable<int>
, or the second overload where T
is int
. Obviously I could make this work by explicitly calling n.Foo<int>()
, but is there a way to make the first overload exclude Nullable<>
from the restriction of what T
can be?
No - both methods are applicable in terms of overload resolution; the type parameter constraints are only checked after the best overload is picked.
There's a really evil way of working round this but personally I'd either give the two methods different names or provide the type argument explicitly.
See more on this question at Stackoverflow