I am a big fan of .NET 4.0’s Tuple classes.
All the items in the Tuples are immutable. There are clearly cases where this is beneficial (most obviously when Tuples are used to represent an ad hoc ValueType for which there is no declaration).
However, I have some use cases where I could see the benefit to a Tuple’s items having setters (with the exception of the TRest Type parameter in the Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>). Given that I have access to the source and to Matt Ellis’s article on “Building Tuple”, it seems like it would be pretty simple to implement such a MutableTuple<T1,T2,TEtc>.
There was clearly a decision by Microsoft to make the Tuple immutable. Is there a reason that I am overlooking that I shouldn’t create an alternate implementation with mutable non-tuple items?
In my opinion, the
Tupleclasses should typically only be used to represent data in a short lived scenario, and only for internal implementation details. For example, they provide convenience when returning multiple values from a private method during a refactoring.As soon as the value becomes part of a public API, or longer becomes longer lived within an API, I personally feel that it becomes much better from a maintainability standpoint to use a custom class or struct which contains the exact properties you need, with appropriate names.
As such – a “mutable tuple” would pretty much, by definition, be something that’s created with the intent of having a longer lifecycle – if you’re going to create it, then later mutate it, you’re effectively saying that the object exists for a purpose. I would recommend a custom class to hold this data at that point, as it provides many advantages in terms of maintainability, including:
The second point, especially, becomes very important over time – if you’re going to be mutating data, you’ll likely have to be validating it at some point to verify that the values are appropriate. If you use a tuple, this validation would have to occur outside of the class containing the data, which is likely to dramatically reduce the maintainability of your code.