Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#为什么字典允许属性设置,尽管属性是内部设置的_C#_Properties_Access Modifiers_Collection Initializer - Fatal编程技术网

C#为什么字典允许属性设置,尽管属性是内部设置的

C#为什么字典允许属性设置,尽管属性是内部设置的,c#,properties,access-modifiers,collection-initializer,C#,Properties,Access Modifiers,Collection Initializer,我正在使用fluent验证API编写验证 我在ValidationContext类上遇到了一个内部集合属性 public class ValidationContext { public Dictionary<string, object> RootContextData { get; internal set; } = new Dictionary<string, object>(); } 上面的代码用于向RootcontextData添加项目 但是下

我正在使用fluent验证API编写验证

我在
ValidationContext
类上遇到了一个
内部集合
属性

public class ValidationContext {
        public Dictionary<string, object> RootContextData { get; internal set; } = new Dictionary<string, object>();
}
上面的代码用于向
RootcontextData
添加项目

但是下面这行直接将另一个字典分配给RootContextData会导致编译时错误

无法将属性或索引器“ValidationContext.RootContextData”分配给--它是只读的

rowItemContext.RootContextData=new Dictionary()
{
{“ab”,新对象()}
};

因此,要将项目字典添加到上下文数据,我必须在要添加的字典上循环。我很惊讶为什么第一个有效,而不是直接赋值。

您似乎对什么算是“设置”属性感到困惑

通常,当您使用
=
符号时,您仅设置属性。使用赋值运算符时,实际上是在为属性赋予一个新值

Dictionary
是引用类型,因此属性存储对Dictionary对象的引用。在本例中,属性的值是指向字典的引用

调用
Add
时,您只是在修改dictionary对象,而不是属性的值。属性的值仍然指向同一个dictionary对象,因此它保持不变


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

有几个时刻:

  • 使用内部集合,因此只能在程序集中设置属性。另见:
  • 在第二种情况下,您使用。它用新值设置属性(用键
    “ab”
    和值
    新对象()初始化的新字典)
  • 如果您遇到这样的异常,尝试在程序集之外执行此操作。使用
    Add
    方法
  • 从设计角度看:不要使用可能改变对象内部状态的公共属性。把它包起来

  • 在第一个示例中,您没有将新对象指定给
    RootContextData
    属性。您正在对现有属性调用
    Add()
    var rowItemContext = new ValidationContext();
    rowItemContext.RootContextData.Add("ab", new object());//this works
    
    rowItemContext.RootContextData = new Dictionary<string, object>()
                {
                    { "ab", new object() }
                };