属性 KeyValuePair.值没有二传手
本文关键字:二传手 Tvalue KeyValuePair TKey 属性 | 更新日期: 2023-09-27 18:34:00
我正在使用Dictionary<int, KeyValuePair<bool, int>>
来保存数据。
有时我需要增加KeyValuePair
中的int
,但它不会让我,因为它没有二传手。有没有办法增加它?
代码示例:
Dictionary<int, KeyValuePair<bool, int>> mDictionary =
new Dictionary<int, KeyValuePair<bool, int>>();
mDictionary[trapType].Value++;
//Error: The property KeyValuePair<TKey, Tvalue>>.Value has no setter
有没有办法增加它?
不。 KeyValuePair
是不可变的 - 它也是一种值类型,因此在创建副本后更改 Value
属性的值无论如何都无济于事。
你必须写这样的东西:
var existingValue = mDictionary[trapType];
var newValue = new KeyValuePair<bool, int>(existingValue.Key,
existingValue.Value + 1);
mDictionary[trapType] = newValue;
虽然这很丑陋 - 你真的需要价值来成为KeyValuePair
吗?
mDictionary[trapType] = new KeyValuePair<bool, int>(mDictionary[trapType].Key, mDictionary[trapType].Value+1)
KeyValuePair
往往只用作字典的迭代器值。如果您希望自己的类型是可变的,则最好定义自己的类型。
另一种解决方案是创建一个新的字典并将新的值和键传递给它:
foreach (var d in existingDic)
newDic.Add(d.Key, d.Value + 1);
从概念上讲,KeyValuePair<TKey,TValue>
只是一对变量,Key
和Value
。 如果Microsoft在暴露的公共领域Key
和Value
来实现它,它的语义将是完美的;当用作ForEach
控制变量时,它将是不可变的,但可以更新普通变量或数组元素的键或值字段,而无需更新另一个。
不幸的是,Microsoft似乎不愿意让框架类型公开任何公共字段,即使是像 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
的单个成员的有用性足以证明第二个成员构成的危险是合理的。 请注意,如果类型使用公开字段而不是属性,则这两个示例都不会造成任何危险,因为写入临时结构的字段从来都不是允许的,即使调用属性 setter 也是如此。
如前所述,KeyValuePair 是不可变的。我认为值得在这里添加一个可变的实现:
public class MutableKeyValuePair<KeyType, ValueType>
{
public KeyType Key { get; set; }
public ValueType Value { get; set; }
public MutableKeyValuePair() { }
public MutableKeyValuePair(KeyType key, ValueType val)
{
Key = key;
Value = val;
}
}
您需要构造一个新的键值对。
mDictionary[trapType] = new KeyValuePair<bool,int>(mDictionary[trapType].Key,mDictionary[trapType].Value +1);
但是,如果您使用的是 .NET 4,如果您尝试做的只是拥有一个包含其他两个值的对象,我建议您使用 Tuple
而不是键值对。即,如果两者之间没有键值关系。然后代码将是:
mDictionary[trapType] = Tuple.Create(mDictionary[trapType].Item1,mDictionary[trapType].Item2 +1);