Как я могу написать стенограмму следующего сценария?
get
{
if (_rows == null)
{
_rows = new List<Row>();
}
return _rows;
}
Как я могу написать стенограмму следующего сценария?
get
{
if (_rows == null)
{
_rows = new List<Row>();
}
return _rows;
}
Используя оператор объединения с нулевым значением ( ?? ):
get
{
_rows = _rows ?? new List<Row>();
return _rows;
}
ИЛИ (менее читаемо):
get { return _rows ?? (_rows = new List<Row>()); }
?? оператор называется оператором объединения с нулевым значением. Он возвращает левый операнд, если операнд не равен нулю; в противном случае возвращается правый операнд.
??
. Это ясно. Что неясно, так это то, какую пользу это имеет по сравнению с кодом, который ОП уже задал в вопросе.
- person ; 09.07.2016
_rows
на односимвольное имя поля и удалив ненужные пробелы. .
- person ; 09.07.2016
??
? Здесь не место обсуждать, полезна ли эта функция с точки зрения удобочитаемости.
- person Zein Makki; 09.07.2016
??
, это не должно быть проблемой для его понимания.
- person Stefan; 09.07.2016
Это шаблон ленивой инициализации, поэтому проще всего использовать Lazy‹T› класс.
class Foo
{
Lazy<List<Row>> _rows;
public Foo()
{
_rows = new Lazy(() => new List<Row>());
}
public List<Row> Rows
{
get { return _rows.Value; }
}
}
Это имеет дополнительное преимущество, заключающееся в том, что он не «загрязняет» геттер логикой инициализации.
Я предлагаю оператор тройной
get {
return _rows == null ? _rows = new List<Row>() : _rows;
}
Или, поскольку пустое List<Row>
не создает больших накладных расходов, почему бы не избавиться от явного поля _row
и реализовать свойство только для чтения (синтаксис C# 6.0):
public IList<Row> Rows {get;} = new List<Row>();
Вот идея получше: не допустить, чтобы _rows
когда-либо становилось null
.
Заставьте ваш конструктор инициализировать переменную:
public MyClass()
{
this._rows = new List<Row>();
}
и тогда ваша собственность просто
get
{
return this._rows;
}
Убедитесь, что если вам нужно «очистить» переменную, вы всегда вызываете ее метод Clear
или назначаете новый пустой список вместо назначения null
. Возможно, закодируйте эту операцию в методе, если вам действительно нужно сделать ее понятной и согласованной во всем классе.
Это намного более логично. Если ваша переменная никогда не должна быть null
, она никогда не должна быть null
. Это также аккуратно избегает как условного, так и проблемы наличия состояния модификации геттера.
MyExpensiveToInitializeClass
. Этот ответ относится к вопросу, как написано, и предполагает, что нет никаких причин для этого, кроме того, что написано. Если есть, то это другой вопрос.
- person jpmc26; 11.07.2016
Как уже говорили другие, в этом сценарии вы можете использовать оператор объединения с нулевым значением.
get
{
return _rows ?? (_rows = new List<Row>());
}
Стоит отметить, что это тот тип изменений, которые ReSharper отлично предлагает (они называют это быстрое исправление).
В вашем примере под оператором if
будет помещена небольшая волнистая линия. При наведении курсора на него отображается предложение о том, как можно изменить код. упрощенный.
Пара кликов позже, и изменение реализовано.
Например, вот так:
get{ return _rows ?? (_rows = new List<Row>()); }
Если вы хотите, чтобы ваш код вел себя как ваш текущий код, лениво инициализируя ваше резервное поле при доступе к свойству, тогда да, вы можете сделать его короче. Вы можете переименовать свое резервное поле, поскольку в ответе уже используется ??
, чтобы поместить все в одно выражение, и когда у вас есть это единственное выражение, используйте новый синтаксис свойств С# 6, чтобы избежать написания get
и return
:
List<Row>_;List<Row> Rows=>_??(_=new List<Row>());
Надеюсь, задолго до того, как вы дойдете до этого момента, вы увидите, что превратили простой для понимания код, который делает именно то, что вам нужно, в ужасный беспорядок, который вы никогда не захотите поддерживать.
Просто оставьте свой код таким, какой он есть. Вы можете сделать его короче, как показано на рисунке, но это не сделает его лучше.
Если проблема в том, что для написания требуется больше времени, потому что вы продолжаете вводить один и тот же код снова и снова, многие IDE предоставляют некоторую функцию для вставки шаблонов, фрагментов или любого другого термина, который они используют для этого. Это позволяет вам определить что-то вроде строк
{Type} {Field};
public {Type} {Property} {
get {
if ({Field} == null) {
{Field} = new {Type}();
}
return {Field};
}
}
где ваш редактор затем предложит вам указать конкретный {Тип}, {Поле}, {Свойство}, без необходимости вводить его каждый раз снова.
Если бы вы действительно хотели сократить его, я бы просто удалил лишние скобки.
get
{
if (_rows == null)
_rows = new List<Row>();
return _rows;
}
Вы можете сделать это любым из следующих способов:
- Условный оператор (?:)
- Оператор объединения с нулевым значением ( ?? )
С условным оператором
get {
return _rows == null ? new List<Row>() : _rows;
}
Оператор объединения с нулевым значением
get {
return _rows ?? new List<Row>();
}
_rows
нет доступа откуда-то еще, то есть... - person KABoissonneault   schedule 08.07.2016return someValueThatMightBeNull;
. Хотите перефразировать вопрос? - person user253751   schedule 10.07.2016null
. - person CodesInChaos   schedule 10.07.2016_rows
не является общедоступным или не установленnull
каким-либо методом в классе. Эти вещи также должны быть изменены. - person PC Luddite   schedule 10.07.2016