C#为什么字典允许属性设置虽然属性是内部集

时间:2018-06-11 10:41:51

标签: c# properties access-modifiers collection-initializer

我使用流畅的验证API来编写验证。

我在internal set课程上遇到了ValidationContext个媒体资源。

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

我遇到了question中的内部设置属性。所以,我可以像这样设置字典的值

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

以上代码将项目添加到RootcontextData

但是直接将另一个字典分配给RootContextData的以下行导致编译时错误。

  

属性或索引器&#39; ValidationContext.RootContextData&#39;无法分配 - 它是只读的

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

因此,要将项目字典添加到上下文数据,我必须遍历要添加的字典。我很惊讶地看到为什么第一个有效而不是直接分配。

2 个答案:

答案 0 :(得分:1)

似乎你对于什么算得很困惑&#34;设置&#34;财产。

通常,当您使用set符号时,您只是=属性。当您使用赋值运算符时,实际为属性赋予新值。

Dictionary是引用类型,因此该属性存储对字典对象的引用。在这种情况下,属性的值是指向字典的引用。

当您致电Add时,您只是修改字典对象,而不是属性的值。该属性的值仍然指向同一个字典对象,因此它保持不变。

当您使用=并创建新词典时,您尝试将存储在该属性中的引用更改为其他引用。这被视为set属性,因此您无法执行此操作。

答案 1 :(得分:0)

有几个时刻:

  1. 您使用内部集,因此您只能在程序集内设置属性。另见:What is internal set property in c#?
  2. 在第二种情况下,您使用Collection Initializer。它使用新值设置属性(使用键"ab"和值new object()初始化的新词典)
  3. 如果你遇到这样的例外,你试图在你的装配之外做这件事。使用Add方法。
  4. 从设计角度来看:不要使用可以改变对象内部状态的公共属性。封装它。