C # - Недостаток установки начального значения в декларации - PullRequest
10 голосов
/ 08 июня 2010

Есть ли недостатки у такого класса, как:

class Example1
{
  protected string UserId = (string)Session["user"];
}
//versus

class Example2
{
  protected string UserId;
  public Example2()
  {
      UserId = (string)Session["user"];
  }
}

Если я всегда хочу установить это значение, есть ли недостаток для Example1?

UPDATE:
Сеанс ["пользователь"] устанавливается в Global.asax Session_Start. Так что, если это не удастся. Ничто не должно работать в любом случае.

Ответы [ 9 ]

5 голосов
/ 08 июня 2010

Ваша самая большая проблема, если это protected string UserId = (string)Session["user"]; не удается.У вас нет возможности изящно деградировать.Поместив его в конструктор и т. Д. Вы можете проверить сессию и принять решение о том, что делать.

Как правило, я только пытаюсь поставить значения, которые, как я знаю, будут успешными, например UserId = -1;и т.д., а затем измените их в блоке кода, когда мне нужно.Вы никогда не знаете, когда что-то пойдет не так, и вам нужно восстанавливаться после этого.

2 голосов
/ 08 июня 2010

Если вы включите отладчик, установка значения в объявлении (пример 1) происходит до вызова конструктора, поэтому вам нужно убедиться, что он не полагается ни на что, настроенное конструктором.

2 голосов
/ 08 июня 2010

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

1 голос
/ 08 июня 2010

AFAIK, нет реальной разницы между инициализаторами встроенных значений и инициализацией конструктора, за исключением порядка выполнения операторов и того факта, что вы очень сильно ограничены однострочными операторами во встроенном коде.

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

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

1 голос
/ 08 июня 2010

Я бы настоятельно рекомендовал использовать "безопасный" актерский состав.

UserId = Session["user"] as string;

Таким образом, если элемент сеанса не существует или не является строкой, вы не ошибетесь. Вы просто получаете нуль, который вы можете проверить перед использованием UserId.

0 голосов
/ 08 июня 2010

AFAIK конструктор всегда вызывается после инициализации всех полей. Таким образом, в Примере 2 вы сначала инициализируете поле Null, а затем (string)Session["user"].

0 голосов
/ 08 июня 2010

Возможно, вы когда-нибудь захотите второй конструктор с другим значением UserId.

0 голосов
/ 08 июня 2010

Трудно понять, как начать говорить, что это не очень хорошая идея по многим причинам.Первый сеанс должен быть глобальной переменной, иначе ваш код даже не скомпилируется.Я предполагаю, что Session в вашем контексте - это System.Web.HttpContext.Current.Session, поэтому ваш код даже не скомпилируется.Предположим, у вас есть Session в качестве глобальной переменной, затем вы должны правильно инициализировать ее и назначить Session ["user"], так как вы собираетесь это сделать?Затем вы создаете эту зависимость между вашим классом и сессией, так как вы тестируете модуль?Плюс все другие причины из всех других ответов.

0 голосов
/ 08 июня 2010

Указание, которое я использую: Используйте инициализаторы полей для основных / значений, известных во время компиляции.Если вы делаете что-то вроде поиска глобальной коллекции или какой-то нетривиальной логики, переместите ее в ctor (для обработки ошибок / восстановления, как указали другие).ошибок не будет, верх *

  • : легко читаются инициализаторы полябудет вставлен вверху каждого ctor, что приведет к некоторому раздутию IL.Так что в этом случае лучше вызывать метод Initialize like.

Кроме этого, я не вижу никаких недостатков для инициализаторов полей.

...