Is there a way I can return more than one integer from a method?

Multiple ways:

  1. out parameters:

    private double GetHeight(out int anotherValue)
    {
        anotherValue = 42;
        return 2;
    }
    
  2. value-tuples:

    private (double height, int anotherValue) GetHeight()
    {
        return (42, 2);
    }
    

    (warning: value-tuples have known problems if used in .NET Standard libraries, as the assembly bindings from .NET Standard to .NET Framework are ... kinda fubar)

  3. custom return types:

    private Something GetHeight()
    {
        return new Something(42, 2);
    }
    

    (to avoid allocations, you may wish to define Something as a readonly struct in this scenario)


Also you could use out parameters:

static void Main(string[] args)
{
  int i, j;
  GetHeight(out i, out j);
}

public static void GetHeight(out int i1, out int i2)
{
  i1 = 1;
  i2 = 2;
}

Yes, you can use Tuple:

class Program
  {
    static void Main(string[] args)
    {
      Tuple<int, int> height = GetHeight();

      Console.WriteLine(height.Item1 + " - " + height.Item2);
      Console.ReadLine();
    }

    private static Tuple<int, int> GetHeight()
    {
      return new Tuple<int, int>(2, 3);
    }
  }

OUTPUT:

2 - 3


Yes ValueTuple / Named Tuple (available in C# 7.0). The advantage is it's the most succinct, it's immutable, and it's easy to construct.

The ValueTuple struct has fields named Item1, Item2, Item3, and so on, similar to the properties defined in the existing Tuple types.

However, when you initialize a tuple, you can use new language features that give better names to each field. Doing so creates a named tuple. Named tuples still have elements named Item1, Item2, Item3 and so on. But they also have synonyms for any of those elements that you have named. You create a named tuple by specifying the names for each element.

private (double first, double second) GetHeight()
{
   return (1,2);
}

...

var result = ViaNamedValueTuple();
Console.WriteLine($"{result.first}, {result.second}");

var (first, second) = ViaNamedValueTuple();
Console.WriteLine($"{first}, {second}");

Classic Tuple

C# tuple type

The .NET Framework already has generic Tuple classes. These classes, however, had two major limitations. For one, the Tuple classes named their properties Item1, Item2, and so on. Those names carry no semantic information. Using these Tuple types does not enable communicating the meaning of each of the properties. The new language features enable you to declare and use semantically meaningful names for the elements in a tuple.

public Tuple<int, int> ViaClassicTuple()
{
   return new Tuple<int, int>(1,2);
}

...

var tuple = ViaClassicTuple();
Console.WriteLine($"{tuple.Item1}, {tuple.Item2}");

Classic struct

struct (C# Reference)

A struct type is a value type that is typically used to encapsulate small groups of related variables, such as the coordinates of a rectangle or the characteristics of an item in an inventory.

public struct ClassicStruct
{
   public int First { get; set; }
   public int Second { get; set; }
   public ClassicStruct(int first, int second)
   {
      First = first;
      Second = second;
   }
}

...

public ClassicStruct ViaClassicStruct()
{
   return new ClassicStruct(1, 2);
}

... 

var classicStruct = ViaClassicStruct();
Console.WriteLine($"{classicStruct.First}, {classicStruct.Second}");

Readonly struct

readonly (C# Reference)

The readonly modifier on a struct definition declares that the struct is immutable. Every instance field of the struct must be marked readonly, as shown in the following example:

public readonly struct ReadonlyStruct
{
   public int First { get; }
   public int Second { get; }
   public ReadonlyStruct(int first, int second)
   {
      First = first;
      Second = second;
   }
}

...

public ReadonlyStruct ViaReadonlyStruct()
{
   return new ReadonlyStruct(1, 2);
}

...


var readonlyStruct = ViaReadonlyStruct();
Console.WriteLine($"{readonlyStruct.First}, {readonlyStruct.Second}");

Simple Class

Classes (C# Programming Guide)

A type that is defined as a class is a reference type. At run time, when you declare a variable of a reference type, the variable contains the value null until you explicitly create an instance of the class by using the new operator, or assign it an object of a compatible type that may have been created elsewhere

public class SomeClass
{
   public int First { get; set; }
   public int Second { get; set; }
   public SomeClass(int first, int second)
   {
      First = first;
      Second = second;
   }
}

...

public SomeClass ViaSomeClass()
{
   return new SomeClass(1, 2);
}

...


var someClass = ViaSomeClass();
Console.WriteLine($"{someClass.First}, {someClass.Second}");

Out parameters

out parameter modifier (C# Reference)

The out keyword causes arguments to be passed by reference. It makes the formal parameter an alias for the argument, which must be a variable. In other words, any operation on the parameter is made on the argument. It is like the ref keyword, except that ref requires that the variable be initialized before it is passed. It is also like the in keyword, except that in does not allow the called method to modify the argument value. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword.

public bool ViaOutParams(out int first, out int second)
{
   first = 1;
   second = 2;
   return someCondition;
}

...

if(ViaOutParams(out var firstInt, out var secondInt))
   Console.WriteLine($"{firstInt}, {secondInt}");

Out Value Tuple

public bool ViaOutTuple(out (int first,int second) output)
{
   output = (1, 2);
   return someCondition;
}

...

if (ViaOutTuple(out var output))
   Console.WriteLine($"{output.first}, {output.second}");

Tags:

C#