The KeyValuePair <TKey, Tvalue> .Value property has no setter
I use Dictionary<int, KeyValuePair<bool, int>>
to store data.
From time to time I need to increase the "int" in KeyValuePair, but that will not allow me because it does not have a setter.
Is there any way to increase it?
code example:
Dictionary<int, KeyValuePair<bool, int>> mDictionary = new Dictionary<int, KeyValuePair<bool, int>>();
in the method:
mDictionary[trapType].Value++; //Error: The property KeyValuePair<TKey, Tvalue>>.Value has no setter
Is there any way to increase it?
Not. KeyValuePair
is immutable - it is also a value type, so changing the value of the Value
property after creating the copy will not help in any case.
You need to write something like this:
var existingValue = mDictionary[trapType]; var newValue = new KeyValuePair<bool, int>(existingValue.Key, existingValue.Value + 1); mDictionary[trapType] = newValue;
This is pretty ugly - do you really need the value to be KeyValuePair
?
Do you want to create a new key value pair
mDictionary[trapType] = new KeyValuePair<bool,int>(mDictionary[trapType].Key,mDictionary[trapType].Value +1);
However, if you are using .NET 4. I would suggest using triples instead of a pair of key values, if what you are trying to do is just have an object that contains two other values. That is, if there is no key value relationship between them. Then the code will be as follows:
mDictionary[trapType] = Tuple.Create(mDictionary[trapType].Item1,mDictionary[trapType].Item2 +1);
Conceptually, KeyValuePair<TKey,TValue>
is just a couple of variables, Key
and Value
. If Microsoft implemented it with the public Key
and Value
public fields, the semantics of this would be ideal; when used as a ForEach
control variable, it would be unchanged, but it would be possible to update the Key or Value field of a regular element or array without having to update another.
Unfortunately, Microsoft does not seem to want the frame types to display any public fields, even for types such as KeyValuePair<TKey,TValue>
or Drawing.Rectangle
, whose semantics dictate that (1) the type should be a structure; (2) all its state is visible in a fixed set of properties (there can be other calculated properties, except for those that determine the state of the object), and (3) any combination of values ββsuitable for their types can be assigned to these properties. Consequently, Microsoft only considered the possibility of exposing elements containing type states as read-only properties, or as read and write properties. Using read-write properties will mean code like:
for each (var item in myDictionary) item.Value += 1;
or
...assuming MyList is a List<Drawing.Rectangle> MyList[3].Width += 9;
will be interpreted by the existing C # compiler as either
for each (var item in myDictionary) { var temp = item; temp .Value += 1; }
or
...assuming MyList is a List<Drawing.Rectangle> { temp = MyList[3]; temp.Width += 9; }
both yielding horrible behavior, which is almost certainly not what the programmer planned. The .net developers decided that the value of the presence of KeyValuePair<TKey,TValue>
individually variable, did not justify the danger posed by the first, but the usefulness of modifying individual Rectangle
members was sufficient to justify the danger posed by the second. Note that no example should it was dangerous if types used open fields, not properties, because writing to a temporary structure field was never valid even when calling properties.
As mentioned earlier, KeyValuePair is unchanged. I thought it was worth adding a mutable implementation here:
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; } }