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:
Nullable<DateTime>, I thought a non-generic method (i.e. without the type parameter) would be considered 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.)
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");
    }
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With