Есть ли любая оборотная сторона к классу как:
class Example1
{
protected string UserId = (string)Session["user"];
}
//versus
class Example2
{
protected string UserId;
public Example2()
{
UserId = (string)Session["user"];
}
}
Если я всегда хочу установить это значение, там какая-либо оборотная сторона к Example1?
ОБНОВЛЕНИЕ:
Сессия ["пользователь"] установлена в Global.asax Session_Start. Таким образом, если это перестало работать. Ничто не должно работать так или иначе.
Самая большая проблема, если это защищенная строка UserId = (строка) Сессия ["пользователь"];
не удалась. У вас нет возможности изящно деградировать. Поместив его в конструктор и т. Д. Вы можете проверить Сессию и принять решение, что делать.
Как правило, я пытаюсь установить только те значения, которые, как я знаю, будут успешными, например UserId = -1;
и т. Д., А затем при необходимости модифицирую их в блоке кода. Вы никогда не знаете, когда что-то пойдет не так, и вам нужно оправиться от этого.
Когда-нибудь вам может понадобиться второй конструктор с другим значением UserId.
AFAIK, нет никакой реальной разницы между инициализаторами значений и инициализацией конструктора, кроме порядка выполнения утверждений, и того факта, что вы очень сильно ограничены однострочными утверждениями в инлайн-коде.
Порядок выполнения заключается в том, что инициализаторы значений выполняются перед любой логикой конструктора, в неспецифическом порядке, поэтому если какие-либо из утверждений инициализации имеют побочные эффекты, вас могут ожидать неприятные сюрпризы. Однако гарантируется, что этот код будет выполнен, поэтому нет возможности добавить дополнительный конструктор позже и забыть инициализировать какое-то поле.
Я предпочитаю использовать (цепочечные) конструкторы, а не инициализацию в строке, потому что так я нахожу код более читабельным, а также я могу делать любые дополнительные проверки, которые могут понадобиться в дальнейшем.
AFAIK конструктор всегда вызывается после инициализации всех полей. Итак, в примере 2 вы сначала инициализируете поле значением Null
, а затем (строка) Session ["user"]
.
Я настоятельно рекомендую использовать «безопасный» слепок.
UserId = Session["user"] as string;
Таким образом, если элемент сеанса не существует или не является строкой, вы не потерпите неудачу. Вы просто получаете нулевое значение, которое можно проверить перед использованием UserId.
Если вы проверяете отладчик, установка значения в объявлении (Пример 1) происходит до вызова конструктора, поэтому вам нужно убедиться, что он не полагается ни на что, настроенное из конструктора.
Руководство, которое я использую: Используйте инициализаторы полей для основных / известных во время компиляции значений. Если вы делаете что-то вроде поиска в глобальной коллекции или какой-то нетривиальной логики, перенесите это в ctor (для обработки/восстановления ошибок, как отмечали другие).
Если вы уверены, что ошибок не будет,
В остальном я не вижу никаких недостатков в инициализаторах полей.
Трудно сказать, как начать говорить, что это не очень хорошая идея по многим причинам. Во-первых, Session должна быть глобальной переменной, иначе ваш код даже не скомпилируется. Я предполагаю, что Session в вашем контексте здесь - это System.Web.HttpContext.Current.Session, поэтому ваш код даже не скомпилируется. Предположим, что у вас есть Session как глобальная переменная, тогда вы должны правильно инициализировать ее и присвоить Session["user"], так как вы собираетесь это сделать? Затем вы создаете зависимость между вашим классом и сессией, так как же вы будете проводить модульное тестирование? Плюс все остальные причины из других ответов.
Основным недостатком является то, что вы можете установить значение только с помощью одного оператора. Если, например, вы хотите проверить, существует ли ключ Session, и если нет, то присвоить ему значение, то вы не сможете сделать это, задав начальное значение.