2012-05-25 50 views
5

,我有以下几个扩展方法,这是在同一个命名空间和装配:方法分辨率可选参数

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 
} 

我的问题是关于方法的分辨率。下面的调用(从另一个命名空间)解析为ObjectExtensions.NullSafeToString当我预计DateTimeExtensions.NullSafeToString

DateTime? dateTime; 
// ... 
dateTime.NullSafeToString("yyyyMMdd"); 

DateTimeExtensions.NullSafeToString卸下可选参数使其解决预期。

C#规范的第7.6.5.2节概述了搜索的命名空间的顺序,但由于上述命令空间位于同一个命名空间中,因此我希望它使用7.6.5.1节中的规则。

我想那会匹配DateTimeExtensions.NullSafeToString因为:

  • 虽然他们都会有Nullable<DateTime>第一参数类型,我想到了一个非通用的方法(即没有类型参数)将被优先考虑。
  • 我虽然参数列表将没有他们的第一个可选参数被认为是

任何人都可以解释,为什么它捡了ObjectExtensions.NullSafeToStringDateTimeExtensions.NullSafeToString? (另外:从这里的其他讨论,我怀疑有些人可能会不赞成使用扩展方法语义来使解引用无效,但我发现用于这种有限的场景,它们使更多的可读代码。我知道Nullable.ToString已经是空安全的,因为Nullable对象本身不是空的,但并不满足参数所包含ToString,并且我发现,明确命名方法指示空安全的目的。)

+2

重载解析适用“少参数==更好”。 –

回答

1

你的问题与扩展方法无关。这是关于重载和可选参数。(C#规范的7.5.3重载决策) 你可以试试这个代码

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

感谢您的回复。我仍然不清楚为什么它通过DateTimeExtensions.NullSafeToString选择ObjectExtensions.NullSafeToString。从7.5.3.1开始: “如果MP是非通用方法且MQ是通用方法,那么MP比MQ好”。 我认为其他一些规则会首先出现,但我不确定哪一条。 – Giles

+0

对不起 - 应该是7.5.3.2“更好的功能成员”。 – Giles