从概念上讲,KeyValuePair<TKey,TValue>
只是一对变量,Key
并且Value
。如果 Microsoft 使用公开的公共字段Key
和来实现它Value
,它的语义将是完美的;当用作ForEach
控制变量时,它是不可变的,但可以更新普通变量或数组元素的 Key 或 Value 字段,而无需更新另一个。
不幸的是,微软似乎一直不愿意让框架类型公开任何公共字段,即使对于像这样的类型,KeyValuePair<TKey,TValue>
或者Drawing.Rectangle
其语义要求(1)类型必须是结构;(2) 它的整个状态在一组固定的属性中是可见的(除了定义对象状态的属性之外,可能还有其他计算属性),以及 (3) 可以为这些属性分配适合其类型的值的任意组合。因此,Microsoft 只考虑了将构成类型状态的成员公开为只读属性或读写属性的可能性。使用读写属性意味着代码如下:
for each (var item in myDictionary)
item.Value += 1;
或者
...assuming MyList is a List<Drawing.Rectangle>
MyList[3].Width += 9;
将由现有的 C# 编译器解释为
for each (var item in myDictionary)
{ var temp = item; temp .Value += 1; }
或者
...assuming MyList is a List<Drawing.Rectangle>
{ temp = MyList[3]; temp.Width += 9; }
两者都会产生可怕的行为,这几乎肯定不是程序员的意图。.net 的实施者认为,让成员KeyValuePair<TKey,TValue>
单独可变的价值并不能证明前者所带来的危险是合理的,但修改个别成员的有用性Rectangle
足以证明 second 所带来的危险是正当的。请注意,如果类型使用暴露字段而不是属性,则这两个示例都不会造成任何危险,因为写入临时结构的字段是不允许的,即使调用属性设置器也是如此。