Возможно ли автоматически реализованное свойство только для чтения? - PullRequest
58 голосов
/ 19 марта 2010

Я нашел тему на MSDN , в которой говорится, что да, это возможно.

Я сделал тест, который, кажется, нарушает это утверждение:

using System;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Foo f = new Foo("1");
            Console.WriteLine(f.Bar); // prints 1
            f.Test("2");
            Console.WriteLine(f.Bar);// successfully prints 2
        }
    }

    class Foo
    {
        public Foo(string b)
        {
            this.Bar = b;
        }

        public string Bar { get; private set; }

        public void Test(string b)
        {
            // this would be impossible for readonly field!
            // next error would be occur: CS0191 or CS0191
            // A readonly field cannot be assigned to (except in a constructor or a variable initializer)
            this.Bar = b; 
        }
    }
}

Где я не прав?

Ответы [ 7 ]

99 голосов
/ 19 марта 2010

Ответ ниже был написан еще в 2010 году. В C # 6 (выпущен в 2015 году) вы можете писать автоматически реализованные свойства только для чтения:

// This can only be assigned to in a constructor
public int Foo { get; }

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

Если бы я управлял миром, это было бы не так. Когда я встречаюсь с некоторыми языковыми дизайнерами на NDC 2010 в июне (пожалуйста, приходите!), Я намереваюсь уговорить, подкупить, уговорить и, как правило, сделать себя недовольным, пока они не согласятся. В конце концов, это всего лишь одна тонкая пластина .

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

// Read-only properties.

... что определенно не так. Рамки с нами согласны:

var prop = typeof(Contact).GetProperty("Name");
Console.WriteLine(prop.CanWrite); // Prints True
8 голосов
/ 19 марта 2010

Свойство доступно только для чтения вне класса Foo. Я думаю, что это то, к чему идет статья.

Но это не то же самое, что помечать переменную ключевым словом readonly.

6 голосов
/ 19 марта 2010

Это сбивает с толку. Вы должны различать только чтение для c # readonly (что означает ключевое слово).

  • только для чтения: они означают, что никто снаружи не может писать напрямую, только читать.
  • C # readonly: вы можете писать в него только в конструкторе, и никогда больше.
4 голосов
/ 20 марта 2010

Нет, сделать автоматически реализованное свойство доступным только для чтения. Для страницы, на которую вы ссылаетесь:

с автоматически внедренными свойствами, требуются и методы доступа get и set

Свойство только для чтения НЕ имеет установленного метода доступа.

Свойство без установленного метода доступа считается доступным только для чтения

1 голос
/ 03 июля 2013

Невозможно создать автоматически реализованное свойство readonly. Если вы попытаетесь скомпилировать класс с автоматически реализованным свойством, вы получите эту ошибку, если он не имеет и get, и set:

'ProjectName.ClassName.Property.get' должен объявить тело, поскольку оно не помечено как абстрактное или внешнее. Автоматически реализованные свойства должны определять как get, так и set accessors.

С предложением, начинающимся с 'Автоматически', являющимся частью ошибки, с которой мы имеем дело.

1 голос
/ 14 октября 2012

Ключевое слово ReadOnly в C # и VB делает то же самое, когда применяется к полю. Они делают так, чтобы поле можно было назначать только во время статической инициализации (если оно помечено как статическое / общее поле) или во время конструктора.

C # не использует ключевое слово readonly для чего-либо еще.

Ключевое слово ReadOnly в VB имеет другое значение применительно к свойству. В этом случае это просто означает, что не существует приемлемого способа присвоения свойству Public (внутренне, поле поддержки может быть изменено другим внутренним кодом, конечно).

1 голос
/ 19 марта 2010

Частный набор не совпадает с readonly.

Подобно методам или полям, ключевое слово private делает видимость сеттера доступной только для самого класса. Другие объекты не могут использовать установщик, но методы самого класса могут вызывать его свободно. Следовательно, ваш тестовый код компилируется и работает нормально.

Он представляется внешним объектам как свойство readonly, но в истинном определении оно не доступно только для чтения.

...