此外,如果您正在使用LINQ并以Ienumerable的形式获取密钥,那么值是否可以更改?延迟加载是否可以发挥作用?
解决方法
Why did the BCL team decide on not allowing changes to the value when looping over dictionary. I understand that the key cannot be changed but why not allow changes to the value?
对于构建字典的团队,我不能说明确,但我可以做一些有根据的猜测.
首先,人们常说好的节目对输出的正确性是严格的,但对他们所接受的东西宽容.我不认为这是一个好的设计原则.这是一个糟糕的设计原则,因为它允许错误的调用者依赖于未定义和不支持的行为.从而产生向后兼容性负担. (我们当然在网络浏览器世界中看到这一点,每个浏览器供应商都被迫与其他浏览器接受错误的HTML兼容.)
组件定义合同 – 他们说他们接受什么信息作为输入,他们支持什么操作,以及他们产生什么结果.当您接受不在合同中的输入或支持不在合同中的操作时,您所做的实际上是制定新合同,合同未记录,不受支持,并且可能在将来被破坏版.你基本上是制造定时炸弹,当它停止时,一个客户(他们可能甚至不知道他们正在做一些不受支持的事情)被破坏,或者组件提供商最终不得不永远支持他们没有的合同.实际上没有注册.
因此,严格执行合同是一个很好的设计原则. IEnumerable对集合的合同是“在迭代时修改集合是非法的”.这个合同的实施者可以选择说“好吧,我碰巧知道某些修改是安全的,所以我会允许那些”,嘿,突然间你不再执行合同了.您正在实施一项人们将依赖的不同的无证合同.
最好简单地执行合同,即使这是不必要的.这样,在将来,您可以自由地依赖于您记录的合同,而不必担心某些来电者已经违反合同并且已经离开合同,并且期望能够永远这样做.
设计一个允许在迭代期间进行值变换的字典会很容易.这样做可以防止组件提供商关闭该功能,并且不需要提供它,因此最好在有人尝试时给出错误,而不是允许调用者违反合同.
第二个猜测:字典类型是未密封的,因此可以扩展.第三方可能会以这样的方式扩展字典,即如果在枚举期间更改了值,则会违反其不变量.例如,假设某人以可以按值排序的方式扩展字典.
当您编写一个接受Dictionary并对其执行某些操作的方法时,您会认为该操作适用于所有字典,甚至是第三方扩展.用于扩展的组件的设计者需要比平时更加小心,以确保对象强制执行其合同,因为未知的第三方可能依赖于该合同的强制执行.因为在迭代期间可能存在不支持更改值的字典,所以基类也不应该支持它;否则就是违反基类的派生类的可替代性.
Also if you are using LINQ and getting the keys back in form of IEnumerable,can the value be changed ?
规则是在迭代字典时不能更改字典.是否使用LINQ进行迭代是无关紧要的;迭代是迭代.
does lazy loading have a role to play?
当然.请记住,定义LINQ查询不会迭代任何内容;查询表达式的结果是查询对象.只有当您遍历该对象时,才会在集合上进行实际迭代.当你说:
var bobs = from item in items where item.Name == "Bob" select item;
这里没有迭代.直到你说出来
foreach(var bob in bobs) ...
对项目的迭代发生了.