Have you ever had a case, when you needed to return more than one parameter from a method? There are a couple of ways to cope with that and tuple might just be what you need.
The problem
Let’s look at the code, where we parse transaction data just to show it on the screen. We have a separate method for that GetTransactionData
.
string Data = "Michał;Breakfast;59;2021-02-13"; var value = new TupleExample().GetTransactionData(Data, out string customer); Console.WriteLine($"Customer {customer} bought an item for {value}"); public class TupleExample { public decimal GetTransactionData(string data, out string customer) { var chunks = data.Split(';'); customer = chunks.First(); return decimal.Parse(chunks[2]); } }
And here is the result:
Possible solutions
There are a couple of ways we can approach this. The one that I proposed in the beginning, passing additional return values as out
parameters seems to be the worst one. Nevertheless, I saw this construction more than once and there are certain cases it might be useful. For example:
var isSuccess = decimal.TryParse("59,95", out decimal result);
Another approach would be creating a new class to return the result, that might look like this:
var transactionData = new TupleExample().GetTransactionData(Data); Console.WriteLine($"Customer {transactionData.Customer} bought an item for {transactionData.Value}"); public class TransactionData { public string Customer { get; set; } public decimal Value { get; set; } } public class TupleExample { public TransactionData GetTransactionData(string data) { var chunks = data.Split(';'); return new TransactionData { Customer = chunks.First(), Value = decimal.Parse(chunks[2]) }; } }
This solution is correct in every way. We created a class to represent what we return from a method. Properties are named correctly.
What if we could achieve the same without creating a new class?
Meet tuples
A tuple is a value type that can store a set of data elements. It is a very flexible structure, similar to dynamic types, so you can set names for your properties. Let’s finish talking and jump into code:
var transactionData = new TupleExample().GetTransactionData(Data); Console.WriteLine($"Customer {transactionData.Customer} bought an item for {transactionData.Value}"); public class TupleExample { public (string Customer, decimal Value) GetTransactionData(string data) { var chunks = data.Split(';'); return (chunks.First(), decimal.Parse(chunks[2])); } }
Have you noticed, that I haven’t changed the code that’s using a method GetTransactionData
? 😲 It is the change that affects only the method itself, but it just makes it simpler and more concise.
Notice how tuple can be defined:
You can create a tuple with new
keyword or with parenthesis.
var tuple = new Tuple<string, decimal>("John", 20); (string, decimal) tuple2 = ("Anna", 30); (string Name, decimal Value) tuple3 = ("Cathrine", 40); Console.WriteLine($"Customer {tuple2.Item1} bought an item for {tuple2.Item2}"); Console.WriteLine($"Customer {tuple3.Name} bought an item for {tuple3.Value}");
You can specify property names, but if you don’t, you can use default names like Item1
, Item2
, etc.
Summary
A tuple is a simple, dynamic type when we don’t want to create a class for just a single usage. It is flexible and easy to create.
Would it be useful for you? I will give it a try 😀
Thank you for the explanation of Tuples. I have heard the term before but never really researched what a Tuple was and/or how to use it. Too many projects to complete and not enough time to research alternative solutions unless absolutely nec
Prior to reading this article, I always used either reference or out parameters to return multiple values from methods. this option will change my approach going forward.
Thank you.