I have just watched a video presenting the new features of C# 7. Among others, it introduces the possibility to return a tuple type (e.g.: (int, int)
, which, I believe, is just a syntactic sugar for Tuple<int, int>
). Thus, if we have a method returning multiple values, there are 3 possibilities in C# on how to do it:
(int first, int second) ReturnTuple()
{
return (1, 2);
}
int ReturnOutParam(out int second)
{
second = 2;
return 1;
}
CustomObject ReturnObject()
{
return new CustomObject
{
First = 1,
Second = 2
};
}
I believe, there are no more ways to do it - if yes, please, correct me.
Which of those three methods is the right one? And in which cases can we use the remaining two? With every new C# release, I have the feeling that there are one or two design patterns that just became obsolete in the .NET world. Some features were very useful (like generics, partials, LINQ, lambdas, async/await or null propagator). Others are very situational (dynamic, nameof). And then there are those that just don't make sense to me (property auto-initializers, tuple return values or local functions).
The out is a keyword in C# which is used for the passing the arguments to methods as a reference type. It is generally used when a method returns multiple values.
Calling a method with an out argument In C# 6 and earlier, you must declare a variable in a separate statement before you pass it as an out argument. The following example declares a variable named number before it is passed to the Int32.
The main benefits of using parameters are: Worksheet data can be analyzed using dynamic user input. Workbooks can be targeted easily to specific groups of users. Worksheets open more quickly because the amount of data on a worksheet is minimized.
A function can have OUT or IN OUT parameters, but this is bad coding practice. A function should have a return value and no out parameter.
For me it still depends on the situation. For example for TryParse
it's still more readable to do:
if (int.TryParse("123", out var i))
{
// i
}
than
var (success, i) = int.TryParse("123");
if (success)
{
// i
}
and in most cases returning more than one value from method is a code smell. You should always wrap what you return into class which describes your values better than First
and Second
.
First and foremost, a tuple like (int, int)
is syntactic sugar for ValueTuple<int, int>
. The differences between Tuple
and ValueTuple
are:
ValueTuple
is a value type, so there's no need to allocate an object on the heapValueTuple
is mutableValueTuple
has (obviously) built-in language support, and it lets you name the tuple items through a custom attribute (TupleElementNamesAttribute
). With Tuple
, you'll only get Item1
, Item2
etc.With each new language version some features become obsolete. For instance, the delegate { }
syntax was superseded by lambdas. You could argue that out
parameters fits in this category, but that's subjective. Yet all the features need to stay there for backwards compatibility.
For instance, bool int.TryParse(string input, out int value)
should have become int? int.TryParse(string input)
with the inclusion of nullable value types to the language, but the old function was already there in the framework, so it had to stay.
My rule of thumb would be: use value tuples for private methods or utility functions, but prefer full-fledged structs for any public API, it just feels cleaner this way. I generally avoid out
params except occasionally for private methods.
I don't get why some of these new features don't make sense to you:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With