Должен ли конструктор инициализировать собственные параметры непосредственно для закрытого члена или через открытое поле (C # centric)? - PullRequest
4 голосов
/ 20 мая 2009

например. какой путь лучше

class Foo {
private string _Bar ; 
  Foo ( string bar)
  {
    _Bar = bar ; 
  }
 public string Bar 
 { 
   get { return _Bar ; //more logic here
   } 
   set { _Bar = value ;   //more logic could be added
  }
 }
}

ИЛИ

class Foo {
private string _Bar ; 
  Foo ( string bar)
  {
    this.Bar = bar ; 
  }
 public string Bar { 
  get { return _Bar ; //more logic could be added } 
  set { _Bar = value ; //more logic could be added }}
}

Редактировать: я знаю, что последний позволяет добавить в него больше логики, но оправдано ли его использование из-за этого ...

Ответы [ 7 ]

6 голосов
/ 20 мая 2009

Какой способ имеет смысл для класса; нет "лучшей практики".

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

Иногда вы хотите сделать то, что можно сделать только в конструкторе, что нарушает то, что вы можете сделать через свойство post-construction, и в этом случае имеет смысл использовать поле.

1 голос
/ 20 мая 2009

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

public class Foo
{
   private string _Bar = String.Empty;

   public string Bar
   {
      get { return _Bar; }
      set 
      {
          if (value == null)
             throw new ArgumentNullException("Bar");
          _Bar = value;
      }
   }

   public Foo(string bar)
   {
      Bar = bar;
   }
}
1 голос
/ 20 мая 2009

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

1 голос
/ 20 мая 2009

Это зависит.

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

0 голосов
/ 20 мая 2009

Я добавлю немного своего ответа «все зависит»: вы пытаетесь найти баланс между тем, чтобы убедиться, что внутреннее состояние остается согласованным, дублированием кода и производительностью.

Я согласен с Адамом П., потому что ваш текущий пример очень прост, это действительно не имеет значения.

Рассмотрим пример, в котором переменная Qux, доступная только для чтения, зависит от Bar и другого члена Baz. Qux довольно дорогостоящий для вычисления, поэтому вы не захотите делать это на лету - это предлагает приватное поле для хранения состояния и его изменения IFF Bar и Baz change.

Таким образом, в вашем конструкторе вы можете публично установить Bar и Baz, зная, что Qux будет разрешен дважды, или отложить разрешение Qux до конца конструктора (и сохранить один вызов разрешения Qux).

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

0 голосов
/ 20 мая 2009

Ваш пример слишком прост, но ваш комментарий "// можно добавить больше логики" указывает на возможность того, что свойство set может быть более сложным, чем простое присвоение частной переменной.

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

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

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

0 голосов
/ 20 мая 2009

Пожалуйста, прочитайте эту прекрасную запись в блоге Эрика Липперта: Автоматически против явных свойств :

Вот вопрос, который я получил от пользователя C # в прошлом году вопрос я получил довольно часто:

Пользователь: с «обычными» явными свойствами я склонен использовать приватный бэк-поле непосредственно изнутри учебный класс. Конечно, с автоматическим собственность, вы не можете сделать это. мой беспокоит то, что в будущем, если я решить, что мне нужно явное свойство для по любой причине, я остался с выбор смены класса реализация использовать новый частный поле, или продолжайте идти через имущество. Я не уверен, что правильно что нужно сделать в этом случае:

Вы говорите «по любой причине», и это ключ. Ответ на ваш вопрос будет полностью зависеть от какая причина была то, что мотивировало изменить.

Если причина, которая мотивировала изменить с автоматически внедренного свойство явно реализовано свойство было изменить семантику собственности вы должны оценить, нужна ли семантика при доступе к собственности из внутри класса идентичны или отличается от желаемой семантики при доступе к собственности из вне класса. [Акцент мой]

...