2012-05-25 84 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