У меня есть следующая пара методов расширения, которые находятся в том же пространстве имен и сборке:
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
приводит к тому, что он разрешается должным образом.
Раздел 7.6.5.2 спецификации C# описывает порядок поиска в пространствах имен, но, поскольку приведенные выше находятся в одном и том же пространстве имен, я ожидаю, что будут использоваться правила из раздела 7.6.5.1.
Я так и думал. d соответствует DateTimeExtensions.NullSafeToString
, потому что:
Nullable
, я подумал, что это необобщенный метод (т.е. без типа параметр) будет рассматриваться в первую очередь.Может ли кто-нибудь объяснить, почему он выбирает ObjectExtensions.NullSafeToString
вместо DateTimeExtensions.NullSafeToString
?
(Кроме того: из других обсуждений здесь я подозреваю, что некоторые люди могут не одобрить использование семантики метода расширения, чтобы сделать разыменование нулевым безопасным, но я считаю, что использование для ограниченных сценариев, таких как этот, делает код более читаемым. Также я знать, что Nullable.ToString
уже является нулевым, потому что сам объект Nullable
не является нулевым, но это не обслуживает параметры для содержащегося ToString
, и я обнаружил, что метод с явным названием указывает на намерение защиты от нулей.)