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

Возможно ли автоматическое использование только для чтения?

Я нашел тему на 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; 
        }
    }
}

Где я ошибаюсь?

4b9b3361

Ответ 1

Ответ ниже был написан в 2010 году. В С# 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

Ответ 2

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

Но это не то же самое, что маркировка переменной с помощью ключевого слова readonly.

Ответ 3

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

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

Ответ 4

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

с автоматически реализованными свойствами, требуется как get, так и set accessor

Свойство только для чтения имеет NO set accessor.

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

Ответ 5

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

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

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

Ответ 6

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

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

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

Ответ 7

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

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

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