C# Почему в словаре разрешено устанавливать свойства, хотя это внутреннее свойство

Я использую свободный API проверки для написания проверок.

Я наткнулся на internal set собственность на ValidationContext учебный класс.

public class ValidationContext {
        public Dictionary<string, object> RootContextData { get; internal set; } = new Dictionary<string, object>();
}

Я наткнулся на свойство внутреннего набора в этом вопросе. Итак, я могу установить значение словаря, как это

var rowItemContext = new ValidationContext();
rowItemContext.RootContextData.Add("ab", new object());//this works

Приведенный выше код для добавления элемента в RootcontextData работает.

Но следующая строка для непосредственного назначения другого словаря для RootContextData приводит к ошибке времени компиляции.

Свойство или индексатор ValidationContext.RootContextData нельзя присвоить - оно доступно только для чтения

rowItemContext.RootContextData = new Dictionary<string, object>()
            {
                { "ab", new object() }
            };

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

2 ответа

Похоже, вы запутались в том, что считать "установкой" свойства.

Как правило, вы только setсвойство при использовании = знак. Когда вы используете оператор присваивания, вы фактически присваиваете свойство новое значение.

Dictionary является ссылочным типом, поэтому свойство хранит ссылку на объект словаря. Значением свойства в этом случае является ссылка, указывающая на словарь.

Когда вы звоните Add, вы просто изменяете объект словаря, а не значение свойства. Значение свойства по-прежнему указывает на тот же объект словаря, поэтому оно остается неизменным.

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

Есть несколько моментов:

  1. Вы используете внутренний набор, так что вы можете устанавливать свойства только внутри вашей сборки. см. также: Что такое внутреннее свойство set в C#?
  2. Во втором случае вы используете Collection Initializer. Устанавливает свойство с новым значением (новый словарь инициализируется ключом "ab" и значение new object())
  3. Если вы получаете такое исключение, вы пытаетесь сделать это вне вашей сборки. использование Add метод.
  4. С точки зрения дизайна: не используйте открытые свойства, которые могут изменить внутреннее состояние вашего объекта. Инкапсулируйте это.
Другие вопросы по тегам