c# – How to return 2 or more values ​​at once in a method?

Question:

It is common to see examples of methods returning one value at a time. I've seen cases where you need to create a class just to pack the data and be able to return more values.

Would using generic classes be the best way to return 2 or more values ​​of different types (int and string) at once in a method?

Via Object (I believe not recommended)

public class DoisInteiros
{
     public int Int1 { get; set;}
     public int Int2 { get; set;}
}
public DoisInteiros RetornaDoisInteiros()
{
     return new DoisInteiros() {Int1 = 1; Int2 = 2}

}

Using Generic Types

public Tuple<int,string> ReturnsIntAndString()
{
    return new Tuple<int, string>(1,"two");
}

Answer:

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. Don't create a class just to group a set of unrelated values.

A 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 created a new tuple system practically making the use of Tuple<> obsolete. And so the tuples will end up being used for more things.

Many times where creating a class doesn't make sense the tuple can be used. Not only because we are dealing with unrelated values, but also cases where the grouped content is fleeting and matters more 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. Nor am I talking about the obvious characteristics that a tuple cannot have because it is not an object such as behavior, for example.

So:

public (int, string) ReturnsIntAndString() => (1, "two");

Or better yet:

public (int inteiro, string texto) ReturnsIntAndString() => (1, "two");

It has numerous advantages to do it this way, including performance and memory management.

Note that in the old tuples the members had names Item1 , Item2 , etc. The new ones will only have these names if you don't name the members.

The tuple creates a new anonymous type. It can be used anywhere a type fits, but being anonymous it can be awkward to abuse it. With the tuple, we can count on structural types. So two independent tuples that have the same signature (same amount 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. And ref will not be used to return more than one value. Unless you need performance.

I don't recommend KeyValuePair precisely because of what I mentioned above. The semantics are 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. It works? Sure, but good programmers produce semantic code first. Obviously if it has more than two members it won't do.

My (various) tests on the code linked in the answer consistently gave the best result for out . Close by 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);
    }
}

See working on ideone . And in .NET Fiddle . Also posted on GitHub for future reference .

Scroll to Top