Are there any principles to keep in mind when using out parameters? Or can I look at them as just a good way to let a method return multiple values?
What did the language designers have in mind when they were specifying the out parameter?
Edit after some thought:
As i'm thinking about it now, I would be inclined to say that excessive use of out parameters could be indicitive of a code-smell. If a method needs to return instances of more than 1 specific type it implies that the method has more than 1 concern, which is a violation of SRP.
One important caveat to keep in mind is that prior to .NET 3.5 SP1, methods that take or return value types are never inlined. This could have large performance implications for small and frequently called methods, such as those of a vector math library.
This is one of the main reasons why the SlimDX vector math library provides overloads that use out parameters instead of return values; it serves as a potential micro-optimization.
Only the same as return values - ie. be careful of anything the called class will retain and use later. On the whole, I do prefer a wrapper object though; makes the calling code a bit more readable.
Personally, I am not too keen on
out
parameters beyond the establishedTryParse
convention. I prefer to return an instance of a specific type that encapsulates the different parameters, as it makes the code much easier to read imo.If you don't want to define specific types for this, you can use the Tuple type in the upcoming .NET framework. Tuples are basically a bunch of values wrapped in a type. They are used a lot in e.g. F#.
I use out parameters when I write static TryParse methods on my classes. Just to keep in sync with the CLR.
Other than that, its probably a better idea to return a class that has what you need on it.
There are two situations where I don't see a problem at all in using
out
parameters, and these situation most often happen along with one another:Comments on the rationale:
out
parameters. That's exactly the opposite for public functions you expect to find in APIs;out
for internal implementation details, that can be very procedural depending on the problem domain.As an example of a semantically "atomic" operation that changes two related but independent variables, here goes some Python code and how I ported it to C# (in a private method):
Python:
C#:
I could not think of a more straightforward way of doing it (but I would love to know possible alternatives).
I generally view out parameters as a "code smell", and will try to refactor to a different approach if I run into them. As someone has already pointed out, commonly the refactoring will be to create a new class that aggregates the values you were going to be returning via out params.