How to resolve this ambiguity in generic extension methods?

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?

Jon Skeet
people
quotationmark

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.

people

See more on this question at Stackoverflow