2010-06-08 1 views
10

Есть ли недостаток класса, как:C# - Даунсайд для установки начального значения в декларации

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

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

Если я всегда хочу, чтобы установить это значение является ли какой-либо недостаток example1?

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

+0

Сессия инициализирована? – ANeves

+0

вопрос об обновлении – BuddyJoe

+0

один из моих fav-приложений оператора коалесцирования UserId = (строка) Session ["user"] ?? "0"; – kenny

ответ

5

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

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

2

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

2

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

+0

Хорошая точка. Я не забуду проверить эти ситуации. +1 – BuddyJoe

1

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

UserId = Session["user"] as string; 

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

+3

Безопасное литье слишком много используется в подобных ситуациях. Если это не строка, я бы предположил, что вы, вероятно, захотите получить ошибку. Вы пишете код в месте firsat, и вы ожидаете строку, поэтому, если это не строка, она должна быть поднята как проблема, которая должна быть исправлена. Я видел, что слишком многие системы демонстрируют странное поведение, потому что неправильный тип был где-то сохранен, и безопасное нажатие скрывает истинную ошибку и делает ее похожим на неинициализированную ошибку переменной. Только мои два цента. –

+0

Его комментарий (добавленный после вашего ответа) указывает, что 'Session [" user "]' * must * является строкой, поэтому исключение было бы лучше, чтобы пресечь проблему в зародыше. – STW

+0

Поднятие исключения всегда должно быть выбором , когда вы знаете, что исключение возможно. Может быть, это право позволить исключение летать в этом случае, но также, может быть, и нет. Безопасное литье дает вам выбор. –

1

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

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

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

0

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

Предполагая, что вы уверены, что не будет никаких ошибок, то

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

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

0

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

0

Возможно, вам понадобится второй конструктор с другим значением UserId.

0

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

Смежные вопросы