同じ名前空間とアセンブリにある次のいくつかの拡張メソッドがあります。
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.NullSafeToString
しているのか、誰でも明確にできますDateTimeExtensions.NullSafeToString
か?
(余談: ここでの他の議論から、逆参照を null セーフにするために拡張メソッドのセマンティクスを使用することに反対する人もいると思いますが、このような限られたシナリオで使用すると、より読みやすいコードになることがわかります。また、Nullable.ToString
既にオブジェクト自体が null ではないため、null セーフですNullable
が、含まれている へのパラメーターには対応していませんToString
。また、明示的に名前が付けられたメソッドが null セーフの意図を示していることがわかりました。)