6

Why those two methods cannot have the same name? Is it because C# compiler does not take the generic type constraints into consideration for overloading? Could it be done in future releases of C#?

public static TValue GetValueOrNull<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
            where TValue : class
{
    TValue value;
    if (dictionary.TryGetValue(key, out value))
        return value;
    return null;
}

public static TValue? GetValueOrNull<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key)
        where TValue : struct
{
    TValue value;
    if (dictionary.TryGetValue(key, out value))
        return value;
    return null;
}
Kilazur
  • 3,089
  • 1
  • 22
  • 48
Pellared
  • 1,242
  • 2
  • 14
  • 29
  • 6
    Names are different here. Don't see any problem. What error you get? – Sergey Berezovskiy Apr 29 '14 at 08:23
  • He changed the names himself, it should be **TValue GetValueOrNull** and **TValue? GetValueOrNull**. – Kilazur Apr 29 '14 at 08:24
  • possible duplicate of [Why can't two methods be declared with the same signature even though their return types are different?](http://stackoverflow.com/questions/584664/why-cant-two-methods-be-declared-with-the-same-signature-even-though-their-retu) – Milan Halada Apr 29 '14 at 08:25
  • @Uriel_SVK: It's not a duplicate of that - the OP hoped that generic constraints would be part of the signature, and they're not. – Jon Skeet Apr 29 '14 at 08:26
  • 1
    See https://msmvps.com/blogs/jon_skeet/archive/2010/10/28/overloading-and-generic-constraints.aspx and https://msmvps.com/blogs/jon_skeet/archive/2010/11/02/evil-code-overload-resolution-workaround.aspx – Jon Skeet Apr 29 '14 at 08:27
  • http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx here is also a good article – Pellared Apr 29 '14 at 08:53

1 Answers1

10

Absolutely correct. See section 3.6 of the C# Language Spec (version 5):

The signature of a method consists of the name of the method, the number of type parameters and the type and kind (value, reference, or output) of each of its formal parameters, considered in the order left to right. For these purposes, any type parameter of the method that occurs in the type of a formal parameter is identified not by its name, but by its ordinal position in the type argument list of the method. The signature of a method specifically does not include the return type, the params modifier that may be specified for the right-most parameter, nor the optional type parameter constraints.

(My emphasis)

So the signature of both methods is effectively:

GetValueOrNull<T1,T2>(IDictionary<T1,T2>,T1)

And:

Overloading of methods permits a class, struct, or interface to declare multiple methods with the same name, provided their signatures are unique within that class, struct, or interface.


Could it be done in future releases of C#?

I doubt it, unless or until type inference becomes an easier problem to solve. Type inference can already take large amounts of time because the compiler usually has to perform a brute-force approach. It having to also consider overload resolution at the same time may be prohibitively expensive given current machines.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448