Почему это DateTime.Теперь свойство, а не метод?


после прочтения этой записи в блоге : http://wekeroad.com/post/4069048840/when-should-a-method-be-a-property,

мне интересно, почему Microsoft выбирает в C#:

DateTime aDt = DateTime.Now;

вместо

DateTime aDt = DateTime.Now();
  • лучшие практики говорят : используйте метод при вызове члена дважды подряд дает разные результаты
  • и DateTime.Now является прекрасным примером недетерминированного метода / свойства.

знаете ли вы если есть какие-либо причины для этого дизайна ?
Или это просто маленькая ошибка ?

6 55

6 ответов:

Я верю в CLR через C#, Джеффри Рихтер упоминает, что DateTime.Теперь это ошибка.

Система.Класс DateTime имеет только чтение Свойство, которое возвращает текущую дату и время. Каждый раз, когда вы запрашиваете это свойство, оно будет возвращать другое значение. Это ошибка, и Microsoft хочет, чтобы они могли бы исправить класс, сделав теперь метод вместо свойства.

CLR via C# 3rd Edition-страница 243

он на самом деле детерминирован; его выход не является случайным, но основан на чем-то вполне предсказуемом.

" текущее время "все время меняется; поэтому, чтобы быть относительно" одинаковым " с каждым вызовом, это значение должно изменяться так, чтобы каждый раз, когда оно вызывается, оно возвращало текущее время.

EDIT:

это только что пришло мне в голову: конечно, два последующих вызова свойства getter можете возврат различных результатов, если что-то изменило значение свойства в промежуточный период. Свойства не должны быть Constants.

Так вот что происходит (концептуально) с DateTime.Now; его значение изменяется между последующими вызовами к нему.

руководящие принципы-это просто, а не жесткие и быстрые правила.

эти рекомендации предназначены для объектов с отслеживанием состояния и на самом деле пытаются сказать, что свойства не должны мутировать объект. значение datetime.Теперь это статическое свойство, поэтому его вызов не изменяет объект. Это также просто отражает естественное состояние времени, ничего не меняется. Это просто наблюдение за постоянно меняющимся таймером.

Так что дело в том, не создавайте свойства, которые изменяют состояние об объекте. Создайте свойства, которые просто наблюдают за состоянием объекта (даже если состояние изменяется внешне).

в качестве другого примера рассмотрим длину строки. Это свойство, но длина строки может меняться от вызова к вызову, если что-то еще изменяет строку внешне. Это в основном то, что происходит, таймер изменяется внешне, теперь просто отражает его текущее состояние так же, как строка.Длина или любой другой такой свойство.

согласно MSDN вы должны использовать свойство, когда что-то является логическим членом данных объекта:

http://msdn.microsoft.com/en-us/library/bzwdh01d%28VS.71%29.aspx#cpconpropertyusageguidelinesanchor1

далее перечислите случаи, когда метод был бы более подходящим. Ирония заключается в том, что одно из правил для метода заключается в его использовании, когда последовательные вызовы могут возвращать разные результаты и, конечно же, теперь, безусловно, соответствует этому критерий.

лично я думаю, что это было сделано, чтобы устранить потребности в дополнительном (), но я нашел отсутствие () запутанным; мне потребовалось некоторое время, чтобы перейти от старого подхода в VB/VBA.

при принятии решения "метод против свойства", предлагаемый тест"будет последовательные вызовы возвращают разные результаты". Я бы предположил, что лучший тест-это аналогичный, но не идентичный вопрос: "будет ли вызов процедуры влиять на результат будущих вызовов тех же или разных подпрограмм?"В большинстве случаев ответы на оба вопроса будут одинаковыми, поскольку на сегодняшний день наиболее распространенной причиной того, что последующие вызовы рутины приведут к иным результатам, чем первый, будет то, что бывший один причинил более поздний вызов для возврата другого результата, чем это было бы в противном случае.

в случае DateTime.Теперь единственный способ, которым один вызов повлияет на значение, возвращенное другим, будет заключаться в том, что время выполнения, затраченное первым вызовом, привело к тому, что второй вызов произошел значительно позже, чем в противном случае. Хотя педант может рассматривать течение времени как побочный эффект изменения состояния первого вызова, я бы предположил, что есть многие свойства, выполнение которых занимает больше времени, чем DateTime.Теперь, и, таким образом, вызов любого из них будет иметь большую вероятность изменения значения, возвращаемого последующим DateTime.А теперь звони.

обратите внимание, что если бы процедура" get time "была виртуальным членом класса, а не статическим членом, это изменило бы баланс в пользу создания метода; в то время как "ожидаемая" реализация не повлияла бы на состояние любого объекта, было бы вероятно-или, по крайней мере, правдоподобно-что некоторые реализации могут иметь побочные эффекты. Например, вызов Now на объекте RemoteTimeServer может попытаться получить время от удаленного сервера, и такая попытка может иметь значительные побочные эффекты для остальной части системы (например, заставляя одну или несколько машин кэшировать информацию о маршрутизации DNS/IP, так что следующая попытка доступа к тому же серверу завершится на 100 мс быстрее).

поскольку нет правил brightline о том, когда использовать метод и свойство, DateTime.Теперь действительно просто читает выставленное свойство состояния сервера, оно может постоянно меняться, но DateTime.Теперь никогда не влияет на состояние какого-либо свойства, объекта или чего-то еще, поэтому это свойство в рамках.