Лучшая практика: свойства средства доступа или методы без параметров?

Какая практика лучше и почему?

bool IsTodayMonday { get { return DateTime.Now.DayOfWeek == DayOfWeek.Monday; } }

Or

bool IsTodayMonday()
{
    return DateTime.Now.DayOfWeek == DayOfWeek.Monday;
}

person maxp    schedule 07.09.2009    source источник


Ответы (10)


Для меня - в этом особом случае - это вообще не имеет значения.

Если вы посмотрите на сгенерированный IL-код, вы заметите, что он в точности. Свойство вызовет создание метода, который производит тот же код IL.

Что касается реализаций .Net, вам, вероятно, следует использовать это свойство. Инфраструктура .Net использует свойства для IsXXX-Functionality, когда параметры не используются, в противном случае используются методы, если только некоторые другие вещи не указывают на то, что использование метода более уместно. (примеры см. в сообщении выше)

Это IL-код, созданный обеими версиями на случай, если вам интересно (я использовал простое консольное приложение и статические методы / свойства)

{
  // Code size       22 (0x16)
  .maxstack  2
  .locals init ([0] bool CS$1$0000,
           [1] valuetype [mscorlib]System.DateTime CS$0$0001)
  IL_0000:  nop
  IL_0001:  call       valuetype [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
  IL_0006:  stloc.1
  IL_0007:  ldloca.s   CS$0$0001
  IL_0009:  call       instance valuetype [mscorlib]System.DayOfWeek [mscorlib]System.DateTime::get_DayOfWeek()
  IL_000e:  ldc.i4.1
  IL_000f:  ceq
  IL_0011:  stloc.0
  IL_0012:  br.s       IL_0014
  IL_0014:  ldloc.0
  IL_0015:  ret
} // end of method Program::get_IsTodayProp

Ваше здоровье!

person 360Airwalk    schedule 07.09.2009
comment
Думаю, вы упустили суть? Я думал, что вопрос заключается в том, какие подсказки свойства и методы дают пользователям классов, а не в том, что позволяет язык. - person kͩeͣmͮpͥ ͩ; 07.09.2009
comment
вот почему я сказал, как Microsoft решает эту проблему в рамках - как для лучшей практики - person 360Airwalk; 07.09.2009

На мой взгляд, в этих ситуациях следует использовать свойства, если только:

  • Звонок стоит дорого, например вызовы базы данных выполняются
  • При вызове свойства возникают побочные эффекты, например другие переменные также устанавливаются
  • Вызов свойства несколько раз дает разные результаты
  • Ваша собственность используется только для установки значений

В вашем примере я бы выбрал недвижимость.

person Razzie    schedule 07.09.2009
comment
Неплохо! Конечно, из каждого правила есть исключения. И я не вправе подвергать сомнению выбор разработчика фреймворка :-) - person Razzie; 07.09.2009
comment
Я бы не сказал, что DateTime.Now действительно ломает точку 3. Я интерпретирую точку 3 так, что она должна возвращать то же значение, если объект находится в том же состоянии. Очевидно, DateTime.Now возвращает другое значение, поскольку состояние объекта изменилось. - person Stephan; 17.09.2009

Свойство должно быть довольно простой оболочкой для значения. Для пользователя свойства оно должно действовать как переменная.

Если он выполняет какой-либо объем работы, имеет побочные эффекты (например, чтение / запись изменяет какое-либо другое состояние в вашем классе) или если он может дать сбой (например, генерировать исключения), то лучше записать его как метод Get, чтобы вызывающий может видеть, что это не просто значение.

Кроме того, это больше зависит от личных предпочтений (считаете ли вы, что свойства должны представлять только конкретные переменные-члены, или их можно использовать для чтения «вычисленных значений», таких как то, что в вашем примере).

person Jason Williams    schedule 07.09.2009

Обычно:

Если вы используете язык, на котором разрешен вариант №1, вам следует его использовать. Он повышает удобочитаемость и предназначен именно для такой работы.

Если вы не можете использовать вариант №1, вам следует использовать методы get / set; т.е.:

bool getIsTodayMonday()
void setIsTodayMonday(bool timetravelingArgument)

Конкретно ваш пример

Я думаю, вы можете придумать аргументы для обоих, хотя я бы выбрал вариант №2, поскольку поля (на мой взгляд) не должны выполнять слишком много вычислений (за исключением проверки и, возможно, преобразования).

person cwap    schedule 07.09.2009
comment
В замешательстве, вы начинаете с того, что говорите, используйте первое, а затем говорите, что воспользуетесь вторым? - person maxp; 07.09.2009
comment
Я тоже запуталась в вашем вопросе ^^ Вы имеете в виду, что из следующего я должен обычно использовать или в случае этого метода, какой я должен выбрать ?. Я отредактирую, чтобы уточнить свои намерения .. - person cwap; 07.09.2009

Для меня IsTodayMonday больше похож на метод, чем на свойство, поэтому я бы выбрал второй вариант. См. Метод против свойства в C # - в чем разница? наглядный пример того, когда использовать свойства вместо методов.

person David Glenn    schedule 07.09.2009

Я бы выбрал в зависимости от того, что вы хотите сообщить пользователю и что происходит в методе. В вашем примере я бы, вероятно, выбрал первую версию. Если расчет посложнее, я бы выбрал вторую версию.

Или с точки зрения пользователей: я бы не возражал, чтобы получить доступ к obj.IsTodayMonday несколько раз, потому что я бы предположил, что для этого не нужны тяжелые вычисления. В случае obj.IsTodayMonday () я бы подумал о кешировании и повторном использовании результата.

Но, конечно, я пишу код именно так. Это зависит от вашей политики.

person Achim    schedule 07.09.2009

Clock.IsTodayMonday предполагает, что это не имеет побочных эффектов или вычислений.

Clock.IsTodayMonday() указывает на возможные побочные эффекты или вычисления.

В вашем случае IsTodayMonday может быть уместным, но, поскольку он идет и запрашивает системные часы, может быть более подходящим назвать его IsTodayMonday().

Может быть, более сложный пример PrimeFactors. Если бы у вас было свойство целого числа с именем PrimeFactors, это показало бы мне, что вы можете вызывать его снова и снова без какого-либо снижения производительности. Однако, если бы существовал метод с именем PrimeFactors(), я бы, вероятно, использовал временную переменную для кеширования результата, если бы он мне понадобился более одного раза, особенно в жестком цикле.

person kͩeͣmͮpͥ ͩ    schedule 07.09.2009
comment
Хорошо, +1. Я тоже так чувствую. В Ruby, как ни странно, мы не делаем различий, и это сводит меня с ума. - person Dan Rosenstark; 07.09.2009

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

person devnull    schedule 07.09.2009

Вы считали

public static bool IsMonday(DateTime date)
{
    return date.DayOfWeek == DayOfWeek.Monday;
}

вместо? Это значительно проще для модульного тестирования, чем исходный метод.

person TrueWill    schedule 07.09.2009

У меня есть около двадцати лет опыта в разработке программного обеспечения в качестве консультанта для ряда различных компаний, а также я работал в компании OEM. Для меня этот вопрос больше похож на вопрос политики компании (руководящие принципы кодирования), и если какая-либо компания хочет выбрать методы, которые помогают в создании простых для понимания и простых для отладки и чтения практик, то им следует выбрать использование Get / Set вместо свойств. Это потому, что, например, при отладке вызывающего класса, который использует свойство из другого класса, кажется, что существует потенциально плохо обрабатываемый доступ к общедоступной переменной (ПЛОХО и выглядит опасно). С другой стороны, если вы увидите там вызов метода Getter / Setter, то вы сразу ЗНАЕТЕ, что это не доступ к общедоступной переменной и что существует функция, обрабатывающая вызов, и она может даже возвращать код ошибки или исключение. , если так выбрано. Любое руководство по кодированию или выбор практики должны основываться на том факте, что этот выбор лучше направляет кодировщиков при написании быстро понятного, надежного (безопасного), переносимого, простого и симметричного кода, удобного для отладки. А должны ли быть другие причины?

person Community    schedule 17.09.2009