Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method resolution in extension methods with optional parameters

I have the following couple of extension methods, which are in the same namespace and assembly:

public static class DateTimeExtensions
{
    public static string NullSafeToString(this DateTime? possiblyNullDateTime, string format, string nullString = "")
}

public static class NullableExtensions
{
    public static string NullSafeToString<T>(this Nullable<T> nullable, string nullString = "") where T : struct
}

My question is about method resolution. The following call (from another namespace) resolves to ObjectExtensions.NullSafeToString when I expected DateTimeExtensions.NullSafeToString:

DateTime? dateTime;
// ...
dateTime.NullSafeToString("yyyyMMdd");

Removing the optional parameter from DateTimeExtensions.NullSafeToString causes it to resolve as expected.

Section 7.6.5.2 of the C# spec outlines the order of the namespaces searched, but because the above are in the same namespace, I'd expect it to use the rules in section 7.6.5.1.

I thought it'd match DateTimeExtensions.NullSafeToString because:

  • Although they'll both have a first parameter type of Nullable<DateTime>, I thought a non-generic method (i.e. without the type parameter) would be considered first.
  • I though the parameter lists would be considered without their optional parameters first

Can anyone clarify why it's picking ObjectExtensions.NullSafeToString over DateTimeExtensions.NullSafeToString?

(Aside: From other discussions on here, I suspect some people may disapprove of using extension method semantics to make dereferencing null-safe, but I find that used for limited scenarios like this, they make for more readable code. Also I know Nullable.ToString is already null-safe because the Nullable object itself isn't null, but that doesn't cater for parameters to the contained ToString, and I find that the explicitly named method indicates the null-safe intent.)

like image 464
Giles Avatar asked May 25 '12 09:05

Giles


1 Answers

Your problem have nothing to do with extension method. It's about overload resolution and optional parameters.(7.5.3 Overload resolution of c# spec) You can try this code

public static string NullSafeToString(DateTime? possiblyNullDateTime, string format, string nullString = "")
    {
        return string.Empty;
    }
    public static string NullSafeToString<T>(Nullable<T> nullable, string nullString = "") where T : struct
    {
        return string.Empty;
    }
    static void Test()
    {
        DateTime? datetime = DateTime.Now;
        NullSafeToString(datetime, "yyyyMMdd");
    }
like image 117
vasile.minea Avatar answered Nov 16 '22 23:11

vasile.minea