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