Domanda

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?

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top