The class must be created if it makes sense, if the content has any special meaning, when the members are actually related and 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 most appropriate 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, making the use of Tuple<>
obsolete. And so the tuples will eventually be used for more things.
Often where creating a class does not make sense the tuple can be used. Not only because we are dealing with unrelated values, but also cases where grouped content is fleeting and matters more to its members than the set.
We can also abuse the use of tuples. There is a lot of case that creating a named object makes more sense. And I'm not even talking about the obvious characteristics that a tuple can not have because it's not an object like behavior, for example.
So:
public (int, string) ReturnsIntAndString() {
return (1, "two");
}
Or even better:
public (int inteiro, string texto) ReturnsIntAndString() {
return (1, "two");
}
There are numerous advantages to doing this, including performance and memory management.
Note that in old tuples members had names Item1
, Item2
, etc. In the new ones they will only have those names if you do not name the members.
The tuple creates an anonymous new type. It can be used anywhere it fits a type, but by being anonymous it can get weird to abuse it. With the tuple we can count on structural types. So two independent tuples that have the same signature (same number of members with the same types in the same order) 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 KeyValuePair
because of what I mentioned 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 listed as a key and value, it should not be used. It works? Of course, but good programmers produce semantic codes first. Obviously if you have more than two members it will not do.
My (multiple) tests in the linked tag in the response consistently gave the best result for out
. Close was the language tuple and much worse 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) {
return (int.TryParse(text, out var result), result);
}
}
}
See running on .NET Fiddle . Also I put it in GitHub for future reference .