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
:
我的问题是关于方法解析的。下面的调用(来自另一个名称空间)解析为objectextense。当我期望datetimeextension .NullSafeToString时:
DateTime? dateTime;
// ...
dateTime.NullSafeToString("yyyyMMdd");
Removing the optional parameter from DateTimeExtensions.NullSafeToString
causes it to resolve as expected.
从DateTimeExtensions删除可选参数。NullSafeToString会使它按照预期的那样解析。
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.
c#规范的7.6.5.2节概述了搜索名称空间的顺序,但是由于上面的名称空间位于同一个名称空间中,所以我希望它使用7.6.5.1节中的规则。
I thought it'd match DateTimeExtensions.NullSafeToString
because:
我以为它会匹配DateTimeExtensions。NullSafeToString因为:
- 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
?
有人能解释一下为什么它会选择目标吗?NullSafeToString 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.)
(顺便说一下:在这里的其他讨论中,我怀疑有些人可能不赞成使用扩展方法的语义来取消对null的安全性,但是我发现,对于这种有限的场景,它们可以使代码更易于阅读。我也知道可以为空。ToString已经是null-safe了,因为Nullable对象本身并不是null,但是这并不满足所包含的ToString的参数,我发现显式命名的方法表明了null-safe意图。
1 个解决方案
#1
1
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
你的问题与扩展方法无关。它是关于重载解析和可选参数的。(7.5.3重载解析c#规范)您可以尝试这段代码。
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");
}
#1
1
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
你的问题与扩展方法无关。它是关于重载解析和可选参数的。(7.5.3重载解析c#规范)您可以尝试这段代码。
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");
}