I still had a few posts which I was planning to write about first, but the simplicity and usefulness of the following discovery prompted me to go ahead and cut in line of my post queue.
.NET 4.0 introduced a set of very interesting new data structures, called tuples. They allow you to easily group a set of strongly typed variables together, without having to create a struct or class for it. A set of easy factory methods allows you to instantiate them with ease.
// The following is a Tuple<int, string>. var data = Tuple.Create( 1, "apple" );
Now how do you go about creating a list of them? Initially I attempted an approach as follows, which made my DRY brain hurt.
var groceryList = new List<Tuple<int, string>> { Tuple.Create( 1, "kiwi" ), Tuple.Create( 5, "apples" ), Tuple.Create( 3, "potatoes" ), Tuple.Create( 1, "tomato" ) };
When Dictionary has such a nice initializer, why can’t we? Well, we can!
The { } syntax of the collection initializer works on any IEnumerable type which has an Add method with the correct amount of arguments. Without bothering how that works under the covers, that means you can simply extend from List, add a custom Add method to initialize your T, and you are done! Here we go …
public class TupleList<T1, T2> : List<Tuple<T1, T2>> { public void Add( T1 item, T2 item2 ) { Add( new Tuple<T1, T2>( item, item2 ) ); } }
… and you have your easily initializable list of tuples!
var groceryList = new TupleList<int, string> { { 1, "kiwi" }, { 5, "apples" }, { 3, "potatoes" }, { 1, "tomato" } };
If that doesn’t make you want to scroll over your existing codebase and start refactoring, this blog probably isn’t for you. 🙂
Another possible solution that doesn’t require you to create a new type is using a Func delegate. Like so:
Func<int, string, Tuple<int, string>> c = Tuple.Create;
var list = new List<Tuple<int, string>>
{
c(1, "apples"),
c(2, "kiwiws"),
};
How do I add 1 extra value every time I do in, so that new values of text boxes are added to the list as well, without making new list all the time?
var ls1 = new List<Tuple>
{
new Tuple(textBox.Text, textBox2.Text)
};
I don’t understand the question. What do you mean by “every time I do in”? Also ‘Tuple’ is a static type, so your above code does not work. As in the blog post written here, you need specify generic parameters.