The class should be created if it makes sense, if the content has any special meaning, when the members are actually related and are part of a single object. Usually when it will be used in more than one place. Do not create a class just to group a set of unrelated values.
The tuple is more suitable when it only serves to return more than one value and does not produce a specific identity.
In fact C# 7 has created a new tuple system virtually rendering the use of Tuple<>
. And so the tuples will end up being used for more things.
Often where creating a class makes no sense the tuple can be used. Not only are we dealing with unrelated values, but also cases where the grouped content is fleeting and matters more to its members than the set.
We can also abuse the use of tuples. There is much case that the creation of a named object makes more sense. And I’m not even talking about the obvious characteristics that a tuple cannot have because it’s not an object as behavior, for example.
Thus:
public (int, string) ReturnsIntAndString() => (1, "two");
Or better yet:
public (int inteiro, string texto) ReturnsIntAndString() => (1, "two");
It has numerous advantages to do this way, including performance and memory management.
Note that in the old tuples members had names Item1
, Item2
, etc. New ones will only have these names if you do not name the members.
The tuple creates an anonymous new type. It can be used anywhere a type fits, but because it is anonymous it can be weird to abuse it. With the tuple we have structural types. So two independent tuples that have the same signature (same number of members with the same types in the same order) they are compatible and it’s like one thing.
out
will tend to become obsolete as well. E ref
will not be used to return more than one value. Unless you need performance.
I do not recommend the KeyValuePair
precisely from what I informed above. The semantics is wrong. a key and value pair is a specialization of a tuple that indicates having a key and a value. If the data is not related as a key and a value, it should not be used. Does it work? Sure, but good programmers produce semantic code first. Obviously if you have more than two members it does not serve.
My (several) code tests linked in the response provided consistently the best result for the out
. Close was the language tuple and much worse the KeyValuePair
.
An example:
using System;
public class Program {
public static void Main() {
var (deuCerto, resultado) = "123".TryParseInt32();
if (deuCerto) Console.WriteLine(resultado);
}
}
namespace System {
public static class StringExt {
public static (bool ok, int result) TryParseInt32(this string text) => (int.TryParse(text, out var result), result);
}
}
Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.
With C# 7.0 you can return
tuples
implicit, in a more organized way, of a look in this tutorial– Marco Giovanni