Gil*_*les 6 .net c# extension-methods resolution optional-parameters
我有以下几种扩展方法,它们位于相同的命名空间和程序集中:
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
}
Run Code Online (Sandbox Code Playgroud)
我的问题是关于方法解决方案.以下调用(来自另一个命名空间)解析为ObjectExtensions.NullSafeToString我预期的时间DateTimeExtensions.NullSafeToString:
DateTime? dateTime;
// ...
dateTime.NullSafeToString("yyyyMMdd");
Run Code Online (Sandbox Code Playgroud)
删除可选参数DateTimeExtensions.NullSafeToString会导致其按预期解析.
C#规范的第7.6.5.2节概述了搜索的命名空间的顺序,但由于上面的命名空间相同,我希望它能使用7.6.5.1节中的规则.
我认为它匹配DateTimeExtensions.NullSafeToString是因为:
Nullable<DateTime>,但我认为首先考虑非泛型方法(即没有类型参数).任何人都可以解释,为什么它捡ObjectExtensions.NullSafeToString了DateTimeExtensions.NullSafeToString?
(旁白:从这里的其他讨论中,我怀疑有些人可能不赞成使用扩展方法语义来解除引用null安全,但我发现用于这种有限的场景,它们会产生更易读的代码.我也知道Nullable.ToString已经知道了null-safe因为Nullable对象本身不是null,但是它不能满足包含的参数ToString,我发现显式命名的方法指示了null安全的意图.)
小智 1
您的问题与扩展方法无关。这是关于重载解析和可选参数的。(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");
}
Run Code Online (Sandbox Code Playgroud)