7

我正在使用 aDictionary<int, KeyValuePair<bool, int>>来保存数据。

有时我需要增加intin KeyValuePair,但它不会让我,因为它没有设置器。有没有办法增加它?

代码示例:

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
4

7 回答 7

22

有没有办法增加它?

No.KeyValuePair是不可变的 - 它也是一种值类型,因此在创建副本后Value更改属性的值无论如何都无济于事。

你必须写这样的东西:

var existingValue = mDictionary[trapType];
var newValue = new KeyValuePair<bool, int>(existingValue.Key,
                                           existingValue.Value + 1);
mDictionary[trapType] = newValue;

虽然它很丑 - 你真的需要价值是 aKeyValuePair吗?

于 2012-05-14T08:47:42.677 回答
0

从概念上讲,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 所带来的危险是正当的。请注意,如果类型使用暴露字段而不是属性,则这两个示例都不会造成任何危险,因为写入临时结构的字段是不允许的,即使调用属性设置器也是如此。

于 2012-12-12T19:52:50.073 回答
0

另一种解决方案是创建一个新字典并将新值和键传递给它:

foreach (var d in existingDic)
                    newDic.Add(d.Key, d.Value + 1);
于 2012-06-19T16:23:01.710 回答
0

您将需要构建一个新的键值对。

mDictionary[trapType] = new KeyValuePair<bool,int>(mDictionary[trapType].Key,mDictionary[trapType].Value +1);

但是,如果您使用的是 .NET 4,我建议您使用 aTuple而不是键值对,如果您想要做的只是拥有一个包含其他两个值的对象。即如果两者之间没有键值关系。那么代码将是:

mDictionary[trapType] = Tuple.Create(mDictionary[trapType].Item1,mDictionary[trapType].Item2 +1);
于 2012-05-14T08:54:13.007 回答
0
mDictionary[trapType] = new KeyValuePair<bool, int>(mDictionary[trapType].Key, mDictionary[trapType].Value+1)
于 2012-05-14T08:47:25.633 回答
0

KeyValuePair往往只是用作字典的迭代器值。如果你希望它是可变的,你最好定义你自己的类型。

于 2012-05-14T08:50:46.560 回答
0

如前所述,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;
        }
    }
于 2017-09-15T10:54:27.933 回答