Here's some syntactic sugar I've discovered recently and I was quite impressed. Please note it requires C# 7.x (Unity 2019 and newer should be ok).
First, a little background:
A typical method in C# returns one value. Until recently, if you wanted to return two values, like an int and a float, you could either use out parameters, or define a helper struct. But there is other way!
Let's take a look on "old" methods first (if you want to see the new way, it' in 4-th point below).
The problem with out parameters is that returning value via them is a bit less readable than a normal return, and the problem with a helper struct is that is has to be defined. Let's see how it looks like, for reference; and then I'll show you a bit more elegant way.
Let's assume we have our method, getSomeData(), which we would like to return two values: integer age and floating point height.
The first 3 examples below are to show you some context, my "discovery" is in the 4-th point :)
1. out parameter version
The typical way, similar to references from C++: we can "return" our values by out parameters:
private void getSomeData(out int age, out float height)
{
age = 100;
height = 170.5f;
}
// Let's use it
private void someMethod()
{
int age;
float height;
getSomeData(out age, out height);
Debug.Log(age); // 100
Debug.Log(height); // 170.5
}
Problem with this? Well, it doesn't quite look like returning a value. It looks like calling a method with parameters.
2. out+return version
We can return one value and get other one via out parameter:
private int getSomeData(out float height)
{
int age = 100;
height = 170.5f;
return age;
}
// Let's use it
private void someMethod()
{
int age;
float height;
age = getSomeData(out height);
Console.WriteLine(age); // 100
Console.WriteLine(height); // 170.5
}
The problem with this version is that either of parameters is returned in a different way. If both are equally important, it looks strange (if not deceptive).
3. Helper struct
We can define a helper struct and return it:
struct PersonalDetails
{
public int age;
public float height;
}
private PersonalDetails getSomeData()
{
int ageToReturn = 100;
float heightToReturn = 170.5f;
return new PersonalDetails
{ age = ageToReturn, height = heightToReturn };
}
// let's use it
private void someMethod()
{
var myDate = getSomeData();
Console.WriteLine(myDate.age);
Console.WriteLine(myDate.height);
}
This version is very clean and readable when we define and call out method, but...
... before that it requires us to create a whole new structure, just for returning two values at once.
4. Sugar in C#7!
So it seems... We can just return two values at once!
private (int age, float height) getSomeData()
{
int ageToReturn = 100;
float heightToReturn = 170.5f;
return (ageToReturn, heightToReturn);
}
// now let's use it
private void someMethod()
{
var myDate = getSomeData();
Console.WriteLine(myDate.age);
Console.WriteLine(myDate.height);
}
Aaand here is our magic. In the method declaration we put (int age, float height) in the place we would normally place the returned type.
Then we can assign it to a variable, and use it - just like that! What's more, we can access the returned values after a dot, refering to them by names from the method declaration.
BTW if you wonder what type is myDate here, Console.WriteLine(myDate.GetType()), gives us:
System.ValueTuple`2[System.Int32,System.Single]
So instead of
var myDate = getSomeData();
...we could write:
(int age, float height) myDate = getSomeData();
Also nice and clean, isn't it?