4
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?

1
  • If your code is representative of your actual usage, the first method (without the constraint) will actually perform everything you need it to. The null check eliminates the null values and Nullable<int>.ToString() produces the same result as int.ToString() when the value is not null. Commented Apr 21, 2015 at 13:55

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Wow. Seriously evil. We are not worthy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.