Разница в С# между различными стилями геттера

Я иногда вижу сокращения в свойствах для получателя. Например. эти два типа:

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 выражения.

Оба доступны только для чтения.