3

I have this

foreach (KeyValuePair<string, Object> tempData in tempList.ToDictionary(x => x.Key, y => y.Value))
{        
    tempData["fahrzeugA"] = "s";
}

But using tempData["fahrzeugA"] = "s"; will not work.

I get:

Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.KeyValuePair'

What is the correct syntax if I have an existing key fahrzeugA, which I want to alter ?

Marco
  • 22,856
  • 9
  • 75
  • 124
kkkk00999
  • 179
  • 2
  • 13

5 Answers5

2

You can apply this :

 var tempList = new List<Test>();
 var dic = tempList.ToDictionary(x => x.Key, y => y.Value);
 foreach (var tempData in dic)
 {
      dic[tempData.Key] = "s";
 }
Linh Tuan
  • 440
  • 3
  • 11
1

You can't change the key value pair since it is an immutable struct. The only way to change it is to create a new instance. That instance would live independent from the dictionary.

If you want to change the value in the dictionary, use the indexer property on the dictionary to change the value.

And even then, the dictionary will go out of scope immediately, so there is no use setting it. It won't affect the original list.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
0

If you have successfully turned your tempList into a dictionary, there can only be one "fahrzeugA" (since all keys must be unique), so looping makes no sense.

You should be able to just say:

var dictionary = tempList.ToDictionary(x => x.Key, y => y.Value);
dictionary["fahrzeugA"] = "s";

If you don't want to create the dictionary in the first place, you could do this:

var matchingKeyValuePair = tempList.SingleOrDefault(x => x.Key == "fahrzeugA");
if (matchingKeyValuePair != null) matchingKeyValuePair.Value = "s";

If you are using a list of .NET KeyValuePair<TKey, TValue>, which is an immutable struct, you can replace the value with a new KeyValuePair, like this:

var matchingIndex = tempList.FindIndex(x => x.Key == "fahrzeugA");
if (matchingIndex >= 0)
    tempList[matchingIndex] = new KeyValuePair<string, string>("fahrzeugA", "s");

Note, this assumes that you only have one item with a key of "fahrzeugA".

devuxer
  • 41,681
  • 47
  • 180
  • 292
  • 1
    I'm not sure that this is what OP was trying to do? I thought that he tries to change the value in `tempList` - not a completely independent dictionary. – Sebastian Schumann Apr 27 '16 at 06:13
  • 1
    Can you actually modify `KeyValuePair` (http://stackoverflow.com/questions/13454721/how-to-modify-a-keyvaluepair-value)? – Dovydas Šopa Apr 27 '16 at 06:17
  • Better - but if the items in `tempList` are of type `KeyValuePair` they`re immutable and a value type. The check for null and changing the value will not work in that case. But I added a comment to the original question that asks for the type of the items in this list. – Sebastian Schumann Apr 27 '16 at 06:19
  • Nearly perfect. I assume that `tempList` is of type `List<>`. That contains a method [FindIndex](https://msdn.microsoft.com/en-us/library/x1xzf2ca(v=vs.110).aspx) method that takes an predicate. Using this you can remove `SingleOrDefault`, check if the returned index is >= 0 and replace the value using lists indexer without `RemoveAt` and `Insert`. This might be a little faster because it doesn't iterate multiple times over the list and it doesn't rearrange the items. – Sebastian Schumann Apr 27 '16 at 06:32
  • @Vera rind Problem with `FindIndex` is that it will find only first element. What if `List` has more than one key with the same name? – Dovydas Šopa Apr 27 '16 at 06:43
  • @DovydasSopa, yes, I mentioned that as an assumption (but the conversion to Dictionary in the OP's code would have failed if this were not the case). – devuxer Apr 27 '16 at 06:44
  • @devuxer True. But OP did not even run his code, because of syntax error. So it still might fail on `ToDictionary`. – Dovydas Šopa Apr 27 '16 at 06:47
  • @DovydasSopa `SingleOrDefault` will also find only the first element. OP's code converted that list into a dictionary. This will fail if multiple items contains the same key. I think that assumption is valid in that case. By the way: OP changes EVERY ITEM to `["fahrzeugA"] = "s"` not only the one that has `Key == "fahrzeugA"`. – Sebastian Schumann Apr 27 '16 at 06:47
  • @DovydasSopa, was the OP's code a runtime error or compile time error? – devuxer Apr 27 '16 at 06:47
  • @devuxer Compile. Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.KeyValuePair' – Dovydas Šopa Apr 27 '16 at 06:48
  • 2
    Anyways, it does not seem that OP will provide WHAT exactlly he wanted to achieve, so we are just guessing here. – Dovydas Šopa Apr 27 '16 at 06:50
  • @DovydasSopa Nailed it. That the reason why I asked for the WHAT OP was trying to do but I don't get an answer until now. – Sebastian Schumann Apr 27 '16 at 06:52
0

If your tempList is List<KeyValuePair<string, Object>> type:

for (var i = 0; i < tempList.Count; ++i) {
    if (tempList[i].Key == "fahrzeugA") {
        tempList[i] = new KeyValuePair<string, object> ("fahrzeugA", "s"); // KeyValuePair<string, object> might be changed with your own type if you use something else.
        break; // If you want to modify only first KeyValuePair.
    }
}
Dovydas Šopa
  • 2,282
  • 8
  • 26
  • 34
  • 1
    This might work if and only if `tempList` contains items of type `KeyValuePair`. But this is first answer that changes `tempList`. – Sebastian Schumann Apr 27 '16 at 06:24
  • @Vera rind True. if it's other type with `Key` and `Value` elements then `new KeyValuePair` would need to be changed with that other type initialization. – Dovydas Šopa Apr 27 '16 at 06:26
0
  1. Check KeyValuePair.Value Property. It's readonly and can't be altered.
  2. ToDictionary creates a new object. You can't alter original object by accessing its elements' value.
  3. You have to remove this specific item from original list and add new item of the same key back.

    var removeIndex = tempList.FindIndex(kp => kp.Key == "fahrzeugA");
    tempList.RemoveAt(removeIndex);
    tempList.Add(new KeyValuePair<string, string>("fahrzeugA", "s"));
    

    If there are multiple "fahrzeugA" items (it's valid in list but not valid in dictionary), use RemoveAll instead.

qxg
  • 6,955
  • 1
  • 28
  • 36