s + " w...">

How to resolve this ambiguity in common 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 cannot determine if I am causing the first overload Foo<T>, where T- Nullable<int>, or the second overload, where T- int. Obviously, I could do 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 Tcould be?

+4
source share
1 answer

No - both methods are applicable in terms of overload resolution; type parameter restrictions are checked only after selecting the best overload.

, , .

+6