Return multiple values ​​from a method

I can think of the following ways to return multiple values ​​from a method (and one that breaks into two methods)

private bool IsCarFaulty(Car car, out string fault) { fault = string.Empty; return false; } 

 private Tuple<bool, string> IsCarFaulty(Car car) { return Tuple.Create(false, string.Empty); } 

 private ResultAndMessage IsCarFaulty(Car car) { return new ResultAndMessage(false, string.Empty); } 

 private bool IsCarFaulty(Car car) { return false; } private string GetCarFault(Car car) { return string.Empty; } 

Basically, my question is: are there situations where it is preferable to another? If I take int.TryParse for an example. It uses the out parameter, but cannot break it into two methods: CanParse and Parse work, if not better.

+7
source share
6 answers

Basically, my question is: are there situations where it is preferable to another?

Of course, but I do not think that there is a general rule that applies to all cases. Just choose the one that will be more comfortable on an individual basis.

I usually avoid using out parameters because they do not work well with Linq.

If I take int.TryParse for an example. It uses the out parameter, but cannot split it into two methods. CanParse and Parse work just as well, if not better.

Of course, this may work, but that means the string will be parsed twice, which is suboptimal.

When int.TryParse was introduced, C # had no nullable types (EDIT: actually it was); Now you can write a method like this:

 public static int? TryParseInt32(string s) { int i; if (int.TryParse(s, out i)) return i; return null; } 
+3
source

The problem with the individual CanParse and Parse methods is that you have to pay the cost of the parsing twice - once at CanParse , and then again at Parse . This can be especially problematic when the parsing is quite complex and time consuming (for example for types like DateTime ).

+4
source

I prefer creating a strongly typed Result object to encapsulate return values ​​from methods when more than one value is returned. However, it is also possible that the need to return multiple values ​​is a sign that your method is doing too much and may be reorganized.

For example, your method returns a bool for whether the car is faulty and a message. Why not return the method an enumerated value for the failure type, and then a method that can translate this value into an error message?

+3
source

Options:

  • out
    • fast , therefore it is used in framework libraries, you cannot trade speed for anything else in those
    • poor design , not suitable for LINQ and any code with codes
    • easy to code
  • Tuple<>
    • slow , creates small objects, rarely is very expensive in practice, although, according to him, it is very well optimized in .NET. However, I found this to be a problem.
    • poor maintainability , no names for fields, the code is not self-documenting
    • easy to code
  • Result
    • slow
    • good maintainability
    • more code

Obviously, no one can say what is best for your particular case, so choose yourself.

+2
source

the best way to return multiple values ​​is to return an object (a class that wraps all your values ​​in properties) i.e.

 private ResultAndMessage IsCarFaulty(Car car) { return new ResultAndMessage(false, string.Empty); } 

c class ResultAndMessage having two properties (bool and string)

+1
source

I prefer bool return using out methods for TryXXX such as TryParse , TryDeque , etc. for several reasons.

  • The "parts" of the result are very different things, and I like that they are stored separately.
  • The return type is the same in all variants of this. So it’s consistent.
  • The out type is always closely related to the type or object called either by the type itself (as in int.TryParse ) or by the type parameter for the type (as in Dictionary<TKey, TValue>.TryGet and ConcurrentQueue<T>.TryDequeue ). So it’s consistent.
  • It becomes an easily recognizable pattern inside .NET. So it’s consistent.

The last point has a downside in that people can turn to it when something is more appropriate (provided that it is entered correctly and successful, and exceptions are thrown, if it is not, it is often better).

In other cases, I avoid out , it does not catch well, which, in turn, is also not very convenient in lambda expressions.

I prefer an object that encapsulates different values ​​when it is most likely to be used on its own. Otherwise, it's just another class you can learn about.

I prefer tuples when there is a good clear reason why something returns two different values ​​at the same time, but this does not correspond to the above question about the new use-object itself.

First of all, I prefer to return only one result.

With an example of a car error, I would either return one object that would represent an error that could be zero if it weren’t faulty — the only object that represented the state of the car from which “no errors were detected” could be a possible value or, most importantly, because cars may have more than one error (and, apparently, are developing several expensive things immediately before the equivalent of your country's NCT / MOT /) of an enumerated or requested object that would allow me to sort through or request to find all faults that would be empty (as in Count == 0 ) if there were no errors.

0
source

All Articles