Подтвердить что ты не робот

Почему, может быть установлено автоматическое свойство только с геттером?

Я создал автоматическое свойство:

public int Foo { get; } 

Это только приемник. Но когда я создаю конструктор, я могу изменить значение:

public MyClass(string name)
{
    Foo = 5;
}

Почему это возможно, хотя это только get-only?

4b9b3361

Ответ 1

Это новая функция С# 6, "Авто-свойства только для Getter", также известная как "Инициализаторы авто-свойств для свойств только для чтения", как обсуждалось в этом статья журнала MSDN "С#: новый и улучшенный С# 6.0" Марка Михаэлиса и в спецификация языка С# 6.0.

Считыватель полей только для чтения доступен только в конструкторе, во всех остальных сценариях поле остается только для чтения и ведет себя по-прежнему.

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

Эта функция считалась такой же важной, как с момента введения Auto-Implemented Properties в С# 3, изменяемые свойства (те, у которых есть геттер и сеттер), стали быстрее писать, чем неизменяемые (те, у которых есть только геттер) что люди испытывали соблазн использовать изменчивые свойства, чтобы избежать необходимости вводить код для поля поддержки, обычно требуемого для свойств только для чтения. В разделе соответствующего раздела Руководства по программированию Microsoft С# больше обсуждается автоматическое внедрение свойств.

Это сообщение в блоге "# 1,207 - С# 6.0 - Инициализаторы автоистории для свойств только для чтения" Шона Секстона Имеет хорошее объяснение и пример следующим образом:

До С# 6.0, если вы хотите свойство только для чтения (неизменяемое), youd обычно используют только поле для чтения, которое инициализируется в конструктор, как показано ниже.

public class Dog 
{
    public string Name { get; set; }

    // DogCreationTime is immutable
    private readonly DateTime creTime;
    public DateTime DogCreationTime 
    {
        get { return creTime; }
    }

    public Dog(string name)
    {
        Name = name;
        creTime = DateTime.Now;
    }
}

В С# 6.0 вы можете использовать автоматически реализованные свойства для реализации свойство только для чтения. Вы делаете это, используя авто-собственность инициализатор. Результат намного чище, чем приведенный выше пример, где мы должны были явно объявить поле поддержки.

public class Dog
{
    public string Name { get; set; }

    // DogCreationTime is immutable
    public DateTime DogCreationTime { get; } = DateTime.Now;

    public Dog(string name)
    {
        Name = name;
    }
}

Более подробную информацию можно найти в dotnet Roslyn repo на GitHub:

Авто-свойства теперь могут быть объявлены без установщика.

Поле поддержки авто-свойства только для гейтера неявно объявлен как readonly (хотя это имеет значение только для отражения цели). Его можно инициализировать с помощью инициализатора на как в приведенном выше примере. Кроме того, свойство getter-only может быть назначается в объявлении типа конструктора, который вызывает значение, которое должно быть назначено непосредственно в базовое поле:

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

и в Спецификация языка С# 6.0:

Автоматически реализованные свойства

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

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

Авто-свойство может необязательно иметь свойство_initializer, которое применяется непосредственно к полю резервного копирования в качестве переменной_инициализатора (Переменные инициализаторы).

Ответ 2

Это новая функция в С# 6, которая позволяет создавать свойства только для чтения и инициализировать их значения из конструктора (или встроенного когда вы их объявляете).

Если вы попытаетесь изменить значение этого свойства вне конструктора, это даст вам ошибку компиляции.

Он доступен только для чтения в том смысле, что после инициализации его значения (встроенного или внутри конструктора) вы не можете изменить его значение.

Ответ 3

Если бы не было возможности инициализировать свойство только для чтения из конструктора (или инициализатора автоматического свойства), то это было бы бесполезно, так как оно всегда возвращало значение по умолчанию для своего типа (0 для чисел, null для ссылочных типов). Та же семантика применяется к полям readonly во всех версиях С#.

Чтобы определить истинное свойство getter-only (которое не может быть инициализировано конструктором), вам нужно указать, что он возвращает как часть определения:

public int Foo { get { return 5; } }

Или, более кратко в С# 6:

public int Foo => 5;

Ответ 4

Функция автоматического свойства была добавлена ​​к языку во время выпуска С# 3.0. Это позволяет вам определить свойство без какого-либо поля поддержки, однако вам все равно нужно использовать конструктор для инициализации этих свойств auto для значения, отличного от значения по умолчанию. С# 6.0 представляет новую функцию, называемую автоисторическим инициализатором, которая позволяет вам инициализировать эти свойства без конструктора, подобного ниже:

Ранее конструктор требуется, если вы хотите создавать объекты используя авто-свойство и инициализировать авто-свойство для значение, отличное от значения по умолчанию, как показано ниже:

public class MyClass
{
    public int Foo { get; }

    public Foo(int foo)
    {
        Foo = foo;
    }
}

Теперь в С# 6.0 можно использовать инициализатор с авто-имуществом означает, что явный код конструктора не требуется.

public string Foo { get; } = "SomeString";

public List<string> Genres { get; } = new List<string> { "Comedy", "Drama" };

Вы можете найти более подробную информацию об этом здесь

Ответ 5

"автоматически загружаемые автоматически свойства"

Прежде всего, я хочу уточнить, что свойство типа

public string FirstName { get; }

Известно как "автоматически обновляемые свойства только для чтения"

Чтобы проверить это, вы можете запустить и проверить вышеуказанный код с помощью Visual Studio. Если вы измените версию языка с С# 6.0 на С# 5.0, то компилятор выкинет следующее исключение Функция "readonly автоматически реализуемые свойства" недоступна на С# 5. Используйте язык версии 6 или выше.

для изменения версии языка С# посетите здесь

Теперь я перехожу к вашему второму вопросу

"Это только getter. Но когда я создаю конструктор, я могу изменить значение"

Microsoft вводит "автоматически реализованные свойства" только для чтения в логике только для чтения. Как известно, ключевое слово "readonly" доступно из С# 1.0. мы используем ключевое слово "readonly" в качестве модификатора в поле и это поле может быть назначено в 2 способами либо во время объявления или в конструкторе в том же класс.

Точно так же значение "автоматически загружаемых автоматически свойств" может быть назначено двумя способами

Way1 (во время объявления):

public string FirstName { get; } = "Banketeshvar";

Way2 (в конструкторе того же класса)

Person()
{
 FirstName  = "Banketeshvar";
}

Чистое свойство ReadOnly

Если вы ищете чисто свойство Readonly, пойдите для этого

public string FullName => "Manish Sharma";

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

"Свойству или индексу 'Person.FullName' не может быть присвоено значение - оно только для чтения"

Ответ 6

Объявленная переменная readonly может быть записана внутри конструктора, но на языках, которые соблюдают атрибут, не может быть изменена после возврата конструктора. Этот определитель был предоставлен в качестве языковой функции, потому что это часто необходимо для полей, значения которых будут варьироваться в зависимости от параметров конструктора (что означает, что они не могут быть инициализированы до начала конструктора), но не придется изменять после возврата конструкторов, но это было только для переменных, открытых как поля. Семантика полей readonly -qualified во многих случаях была бы идеальна для публичных участников, за исключением того, что для классов часто лучше показывать участников - даже неизменяемых - как свойств, а не полей.

Подобно тому, как существуют автоматические свойства чтения и записи, позволяющие классам выставлять изменчивые свойства так же легко, как обычные поля, существуют только авторизованные свойства для чтения, позволяющие классам выставлять неизменяемые свойства так же легко, как readonly -qualified fields. Так же, как readonly -qualified поля могут быть записаны в конструкторе, поэтому тоже с свойствами get-only.