When should I use out parameters?

后端 未结 10 1298
温柔的废话
温柔的废话 2020-12-08 06:34

I don\'t understand when an output parameter should be used, I personally wrap the result in a new type if I need to return more than one type, I find that a lot easier to w

相关标签:
10条回答
  • 2020-12-08 06:45

    I think out is useful for situations where you need to return both a boolean and a value, like TryParse, but it would be nice if the compiler would allow something like this:

    bool isValid = int.TryParse("100", out int result = 0);
    
    0 讨论(0)
  • 2020-12-08 06:48

    Creating a type just for returning values sounds little painful to me :-) First i will have to create a type for returning the value then in the calling method i have assign the value from the returned type to the actual variable that needs it.

    Out parameters are simipler to use.

    0 讨论(0)
  • 2020-12-08 06:53

    If you always create a type, then you can end up with a lot of clutter in your application.

    As said here, one typical use case is a TrySomething Method where you want to return a bool as an indicator for success and then the actual value. I also find that a little bit cleaner in an if-statement - all three options roughly have the same LOC anyway.

    int myoutvalue;
    if(int.TryParse("213",out myoutvalue){
        DoSomethingWith(myoutvalue);
    }
    
    vs.
    
    ParseResult<int> myoutvalue = int.TryParse("213");
    if ( myoutvalue.Success ) {
        DoSomethingWith(myoutvalue.Value);
    }
    
    vs.
    
    int? myoutvalue = int.TryParse("213");
    if(myoutvalue.HasValue){
        DoSomethingWith(myoutvalue.Value);
    }
    

    As for the "Why not return a Nullable Type": TryParse exists since Framework 1.x, whereas Nullable Types came with 2.0 (As they require Generics). So why unneccessarily break compatibility or start introducing inconsistencies between TryParse on some types? You can always write your own extension Method to duplicate functionality already existing (See Eric Lipperts Post on an unrelated subject that includes some reasoning behind doing/not doing stuff)

    Another use case is if you have to return multiple unrelated values, even though if you do that that should trigger an alarm that your method is possibly doing too much. On the other hand, if your Method is something like an expensive database or web service call and you want to cache the result, it may make sense to do that. Sure, you could create a type, but again, that means one more type in your application.

    0 讨论(0)
  • 2020-12-08 06:56

    Well as with most things it depends. Let us look at the options

    • you could return whatever you want as the return value of the function
    • if you want to return multiple values or the function already has a return value, you can either use out params or create a new composite type that exposes all these values as properties

    In the case of TryParse, using an out param is efficient - you dont have to create a new type which would be 16B of overhead (on 32b machines) or incur the perf cost of having them garbage collected post the call. TryParse could be called from within a loop for instance - so out params rule here.
    For functions that would not be called within a loop (i.e. performance is not a major concern), returning a single composite object might be 'cleaner' (subjective to the beholder). Now with anonymous types and Dynamic typing , it might become even easier.

    Note:

    1. out params have some rules that need to be followed i.e. the compiler will ensure that the function does initialize the value before it exits. So TryParse has to set the out param to some value even if parse operation failed
    2. The TryXXX pattern is a good example of when to use out params - Int32.TryParse was introduced coz people complained of the perf hit of catching exceptions to know if parse failed. Also the most likely thing you'd do in case parse succeeded, is to obtain the parsed value - using an out param means you do not have to make another method call to Parse
    0 讨论(0)
  • 2020-12-08 06:58

    It does annoy me that I can't pass in null to the out parameter for the TryParse functions.

    Still, I prefer it in some cases to returning a new type with two pieces of data. Especially when they're unrelated for the most part or one piece is only needed for a single operation a moment after. When I do need to save the resulting value of a TryParse function I really like having an out parameter rather than some random ResultAndValue class that I have to deal with.

    0 讨论(0)
  • 2020-12-08 07:01

    Definitely, out parameters are intended to be used when you have a method that needs to return more than one value, in the example you posted:

    public void Do(int arg1, int arg2, out int result)
    

    It doesn't makes much sense to use an out parameter, since you are only returning one value, and that method could be used better if you remove the out parameter and put a int return value:

    public int Do(int arg1, int arg2)
    

    There are some good things about out parameters:

    1. Output parameters are initially considered unassigned.
      • Every out parameter must be definitely assigned before the method returns, your code will not compile if you miss an assignment.

    In conclusion, I basically try use out params in my private API to avoid creating separate types to wrap multiple return values, and on my public API, I only use them on methods that match with the TryParse pattern.

    0 讨论(0)
提交回复
热议问题