![]() |
|
Tutorial C# - Returning multiple values - Printable Version +- Sinisterly (https://sinister.ly) +-- Forum: Coding (https://sinister.ly/Forum-Coding) +--- Forum: Visual Basic & .NET Framework (https://sinister.ly/Forum-Visual-Basic-NET-Framework) +--- Thread: Tutorial C# - Returning multiple values (/Thread-Tutorial-C-Returning-multiple-values) |
C# - Returning multiple values - phyrrus9 - 03-18-2020 Have you ever been stuck in the position where your method may need to return more than one thing, and don't know a way out? Take for example, if you were writing a function that performed integer division: Code: int Divide(int numerator, int denominator)
{
int div = 0;
while (numerator >= denominator)
{
++div;
numerator -= denominator;
}
return div;
}Code similar to this is fairly common on embedded platforms where integer division is necessary and no built in instructions can handle it. Anybody that knows anything about division using this method knows that it also computes the modulo, which is simply the numerator at the end of the while loop. What if you wanted to output the result in a format such as this: Code: 10/7: 1 3/10Code: int Mod(int numerator, int denominator)
{
while (numerator >= denominator)
numerator -= denominator;
return numerator;
}Code: void ComputeAndPrint(int numerator, int denominator)
{
int div = Divide(numerator, denominator);
int mod = Mod(numerator, denominator);
Console.WriteLine($"{numerator}/{denominator}: {div} {mod}/{denominator}");
}By now, you've realized that we actually do division twice here, and you're probably wishing you can return multiple values. There are a few ways to do this. I'll outline them from worst to best. Option 1: a struct You can always make a divmod struct, and have the divide function simply return both numbers in it, like so Code: struct divmod
{
public int div;
public int mod;
}
divmod Divide(int numerator, int denominator)
{
divmod result = new divmod { div = 0 };
while (numerator >= denominator)
{
++result.div;
numerator -= denominator;
}
result.mod = numerator;
return result;
}
void ComputeAndPrint(int numerator, int denominator)
{
divmod result = Divide(numerator, denominator);
Console.WriteLine($"{numerator}/{denominator}: {result.div} {result.mod}/{denominator}");
}Option 2: out variables This one is used extensively by many, and I hate it almost as much, but the general concept is that you return one value and pass a parameter that is filled by the method itself, similar to C's use of pointer parameters. It would go something like this: Code: int Divide(int numerator, int denominator, out int mod)
{
int div = 0;
while (numerator >= denominator)
{
++div;
numerator -= denominator;
}
mod = numerator;
return div;
}
void ComputeAndPrint(int numerator, int denominator)
{
int div = Divide(numerator, denominator, out int mod);
Console.WriteLine($"{numerator}/{denominator}: {div} {mod}/{denominator}");
}Option 3: Tuples Thankfully, the answer is yes. C# comes built in with a data type called Tuple. It's basically an anonymous struct that you can put more than one value into. Don't be confused by the name though, you can put more than 2 values into it. Let's have a look at what the tuple implementation looks like. Code: Tuple<int, int> Divide(int numerator, int denominator)
{
int div = 0;
while (numerator >= denominator)
{
++div;
numerator -= denominator;
}
return new Tuple<int, int>(div, numerator);
}
void ComputeAndPrint(int numerator, int denominator)
{
Tuple<int, int> result = Divide(numerator, denominator);
Console.WriteLine($"{numerator}/{denominator}: {result.Item1} {result.Item2}/{denominator}");
}Option 4: deconstructed tuples Again, our answer is yes. In C#8, tuples can be defined, named, and created without the need to explicitly define every aspect of them or use the new keyword. This is done simply by wrapping 2 or more variables within parens. I'll go ahead and write out the basic code for that: Code: (int, int) Divide(int numerator, int denominator)
{
int div = 0;
while (numerator >= denominator)
{
++div;
numerator -= denominator;
}
return (div, numerator);
}
void ComputeAndPrint(int numerator, int denominator)
{
(int, int) result = Divide(numerator, denominator);
Console.WriteLine($"{numerator}/{denominator}: {result.Item1} {result.Item2}/{denominator}");
}Code: void ComputeAndPrint(int numerator, int denominator)
{
(int div, int mod) result = Divide(numerator, denominator);
Console.WriteLine($"{numerator}/{denominator}: {result.div} {result.mod}/{denominator}");
}Code: void ComputeAndPrint(int numerator, int denominator)
{
(int div, int mod) = Divide(numerator, denominator);
Console.WriteLine($"{numerator}/{denominator}: {div} {mod}/{denominator}");
}Code: (int div, int mod) Divide(int numerator, int denominator)Here's the final code for your reference: Code: (int div, int mod) Divide(int numerator, int denominator)
{
int div = 0;
while (numerator >= denominator)
{
++div;
numerator -= denominator;
}
return (div, numerator);
}
void ComputeAndPrint(int numerator, int denominator)
{
(int div, int mod) = Divide(numerator, denominator);
Console.WriteLine($"{numerator}/{denominator}: {div} {mod}/{denominator}");
}Hopefully this quick tutorial helped you, let me know if you want to see more quick tips like this RE: C# - Returning multiple values - bumbuls6 - 11-26-2023 The only thing VB has going for it is the basic syntax if you grew on it so it has a sorta nostalgic value ("muh goto"). |