Search code examples
c#dictionarytuplesvalue-type

Setting dictionary tuple values directly


Is it possible to do something similar to this: dictTupleTest[key].Item1 = toggle; in the following situation?

Dictionary<int, (bool, bool)> dictTupleTest = new Dictionary<int, (bool, bool)>();
var key = 3;
var toggle = false;

dictTupleTest.Add(key, (true, false));

//This works
dictTupleTest[key] = (toggle, dictTupleTest[key].Item2);

//While this gives an error
dictTupleTest[key].Item1 = toggle;

The error: Error CS1612: Cannot modify the return value of 'Dictionary<int, (bool, bool)>.this[int]' because it is not a variable.

Or is there a better way to do it?


Solution

  • Tuples are immutable; the fact that it's stored in a dictionary is irrelevant. You'd get the same error with:

    var x = dictTupleTest[key];
    x.Item1 = toggle;
    

    If you want to change one of the values, then don't use a tuple - use a mutable class. Otherwise, the way you're doing it is appropriate (keeping the second value).

    EDIT -

    Thanks to Theodor Zoulias for pointing out that my reasoning was flawed. The tuple is mutable, but for some reason (I'm not sure why), you can't change a property of the tuple inline with a dictionary accessor. That error is more common when you try to use mutation operators on a return value (like dictTupleTest[key]++), but I don't see why calling a property set shouldn't be allowed.

    In any case, assigning the result to a variable does work:

    dictTupleTest.Add(key, (true, false));
    var x = dictTupleTest[key];
    x.Item1 = false;
    
    Console.WriteLine(dictTupleTest[key]);  // outputs (false, false)