When you really have to return two values (like a return state with various values for success and failure, and some more substantive sought object on success
), resorting to an out parameter seems so obvious, and the relevant static analysis rule does say
It is safe to suppress a warning from this rule. However, this design could cause usability issues.
So "real programmers" will reach for that, regarding the rule as one to mollycoddle junior developers; and will shy from the clunkiness of an anonymous tuple type (even now we have them in core .net languages). But there is still a point where they cause pain, and that is when the parameter is on an interface method, and you want to mock that method.
At this point you have to individually specify each invocation of the mocked method and its pre-computed out parameters -- even though with modern mocking frameworks like Moq, you can use a lambda to compute the return value based on arbitrary inputs, and make a normal mocked method algorithmic over expected inputs.
Upshot -- the usability issue is not that the caller has to look at two values like a success state, and then if relevant a different value, rather than look at fields in some carrying type; it's that your customers (in the Total Quality sense) will end up with rather more coupled and brittle unit tests when they try to abstract your component away through its interface.