UGMFree
The home of SyMenu
Tips in C#
This page is a reminder and how-to for my best tips in C#


How to return multiple parameters from functions: the tuples way

Often it's useful to return more than one parameter from a function.
In the following example we have to pass to caller two values: one string and one int.

There are several solution to this problem applicable in C# language.

1) The function requests one or more input parameters with keyword out (or ref).
In this way the caller can receive a 'normal' return parameter and one or more out parameters that contains the other values.

public string ReturnTwoParams(out int param2) 
{
  param2 = 10;
  return "string value";
}

private void Test()
{
  string param1;
  int param2;
  param1 = ReturnTwoParams(out param2);
}

This is a vintage method difficult to read and not elegant. In other words a so called 'gemyan' practice.


2) The return parameters are boxing inside an array/list/collection of objects.
This is the worst solution because our poor string and int have to be boxed into two objects and then unboxed into the original types. In this manner we lost type safety and performance.


3) The return parameters are enclosed in a typed structure or in a class. Very OOP!

public struct ParametersStructure 
{
  public string param1;
  public int param2;
}

public ParametersStructure ReturnTwoParams()
{
  ParametersStructure ps;
  ps.param1 = "string value";
  ps.param2 = 10;
  return ps;
}

private void Test()
{
  ParametersStructure ps= ReturnTwoParams();
  string param1 = ps.param1;
  int param2 = ps.param2;
}

This is the OOP way. Very boring to code. Every function that returns something more than a parameter, needs all this coding. But the worst thing is that our project starts to fill up of useless classes and structures. I'm saying that this kind of types are useless because they don't represent an entity but they are only a vehicle to workaround a limitation of C#.


4) The return parameter is a tuple of generics.
A tuple is a function that links various attributes to structured values extracted from one or more relation's domains.
In C# we can mimic the tuple function using generics to maintain type safety.
For first we have to create a Tuple class like this one:

public class Tuple<T1>
{
  public T1 param1;

  public Tuple(T1 t1)
  {
      param1 = t1;
  }
}

public class Tuple<T1, T2> : Tuple<T1>
{
  public T2 param2;

  public Tuple(T1 t1, T2 t2) : base(t1)
  {
      param2 = t2;
  }
}

public class Tuple<T1, T2, T3> : Tuple<T1, T2>
{
  public T3 param3;

  public Tuple(T1 t1, T2 t2, T3 t3) : base(t1, t2)
  {
      param3 = t3;
  }
}

First Class (Tuple<T1>) is useful only for inheritance because we don't have any problem to return one single parameter.
Second and third classes are more interesting. Let's see how our problem could be solved.

public Tuple<string,int> ReturnTwoParams()
{
  Tuple<string, int> retParam = 
      new Tuple<string,int>("string value", 10);
  return retParam;
}

private void Test()
{
  Tuple<string, int> retParam = ReturnTwoParams();
  string param1 = retParam.param1;
  int param2 = retParam.param2;
}

Simple and type safe! Our return parameter is a tuple that contains our two variables. We can accede to both variables in a type safe manner without casting and without danger of runtime errors.
The Tuple class, for his nature, could be written one time for the entire project and used by any methods.
If you need more than three return parameters, you can write the Tuple<T1, T2, T3, T4> class and so on.
Thanks to Luca Bolognese and his wonderful blog for this nice trick.
UGM.NET ©2002-2014
By Gianluca Negrelli - Contact me