Разница в С# между различными стилями геттера
Я иногда вижу сокращения в свойствах для получателя. Например. эти два типа:
public int Number { get; } = 0
public int Number => 0;
Может кто-нибудь скажет мне, есть ли различия между этими двумя. Как они себя ведут? Оба они доступны только для чтения?
Ответы
Ответ 1
Да, оба они доступны только для чтения, но есть разница. В первом из них, есть поле подложки, которая инициализируется в 0 до конструктора выполняется. Вы можете изменить значение только в конструкторе, как в обычном поле только для чтения. Сам getter просто возвращает значение поля.
Во втором, он просто возвращает 0 каждый раз, без использования поля.
Итак, чтобы вообще не использовать любые автоматически реализованные свойства или элементы, связанные с выражением тела, мы имеем:
Первая версия
private readonly int _number = 0;
public int Number { get { return _number; } }
Вторая версия
public int Number { get { return 0; } }
Более ясный пример разницы можно увидеть следующим образом:
public DateTime CreationTime { get; } = DateTime.UtcNow;
public DateTime CurrentTime => DateTime.UtcNow;
Если вы создаете один объект, его свойство CreationTime
всегда будет давать тот же результат - потому что он хранится в поле readonly, инициализированном при построении объекта. Однако каждый раз, когда вы получаете доступ к свойству CurrentTime
, это приведет к оценке DateTime.UtcNow
, поэтому вы получите потенциально другой результат.
Ответ 2
Одно отличие заключается в том, когда оценивается 0
: при создании объекта или при использовании свойства.
Вы можете увидеть это лучше с помощью свойств DateTime:
class SomeTestClass
{
public DateTime Start { get; } = DateTime.Now;
public DateTime Now => DateTime.Now;
}
Свойство Start
сохраняет одно и то же время (когда был создан экземпляр), а Now
изменяется, чтобы отразить текущее время.
Объяснение
Первая версия ( "Пуск" ) предоставляет начальное значение, которое может даже быть перезаписано конструктором. Так что это оценивается только один раз.
Вторая версия ( "Сейчас" ) предоставляет выражение, которое будет "получателем" этого свойства. Таким образом, это оценивается каждый раз, когда свойство считывается. Нет даже поля поддержки, которое может перезаписать конструктор.
Ответ 3
Это языковые функции С# 6.
Первый пример
public int Number { get; } = 0
Первый пример - свойство автозапуска только для геттера. Поле поддержки авто-свойства только для гейтера неявно объявляется как readonly.
Второй пример
public int Number => 0;
И второй пример: тела выражений на объектах, подобных свойствам. Обратите внимание, что ключевое слово get
не существует: подразумевается использование синтаксиса body выражения.
Оба доступны только для чтения.