可选参数的扩展方法中的方法解析

时间:2020-12-08 10:55:29

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");
    }