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
тинг собственности, так что вы не можете сделать это.
Есть несколько моментов:
- Вы используете внутренний набор, так что вы можете устанавливать свойства только внутри вашей сборки. см. также: Что такое внутреннее свойство set в C#?
- Во втором случае вы используете Collection Initializer. Устанавливает свойство с новым значением (новый словарь инициализируется ключом
"ab"
и значениеnew object()
) - Если вы получаете такое исключение, вы пытаетесь сделать это вне вашей сборки. использование
Add
метод. - С точки зрения дизайна: не используйте открытые свойства, которые могут изменить внутреннее состояние вашего объекта. Инкапсулируйте это.