views:

557

answers:

9

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.

A: 

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.

pdr
+1  A: 

While out parameters have their use, before using one you should stop and think if you really need it. You may be able to come up with a simpler, cleaner implementation that does not require out.

why-are-out-parameters-in-net-a-bad-idea has more information.

Justin Ethier
+7  A: 

The class design tools specifically say to "Avoid out parameters", with a long discussion for the rationale.

Unless there is a good reason to use an out parameter for a method, it is typically better to make a custom class or struct to hold your results. Using out parameters reduces the usability of an API.

Reed Copsey
FXCop rule " Avoid out parameter" :http://msdn.microsoft.com/en-us/library/ms182131.aspx
ram
+1 for returning a custom class or struct.
Jon Seigel
+15  A: 

Personally, I am not too keen on out parameters beyond the established TryParse 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#.

Brian Rasmussen
I don't really like TryParse either.
recursive
@recursive: Me neither, but since it is in the BCL it is hard to avoid entirely.
Brian Rasmussen
I haven't yet been able to come up with a fragerent alternative to `TryParse`. I would love to hear some ideas (for custom objects, of course)!
Jeffrey L Whitledge
"I would love to hear some ideas", Brian already mentioned the Tuple, and this is pretty much why it exists.
Richard Hein
@Richard Hein - Tuples, eh? Yeah, I heard of them. I have a futuristic music box in my pocket, and the door at work opens when I wave a piece of plastic at it, but I am not living as far into the future as you are!
Jeffrey L Whitledge
@Jeffrey L Whitledge: You can implement tuples yourself (or use a 3rd party library) ... doesn't have to be 4.0. Sounds like you are living inside your futuristic music box and need to think a little outside of it. ;-) Cheers.
Richard Hein
+9  A: 

Using out parameters at all is generally bad practice. It typically indicates a method that is doing more than one well defined thing. The only time I recommend using them is for Interop scenarios where they are sometimes necessary because of the signature of the API.

dkackman
Agreed. If the method is returning more than one **related** value, a class or a struct or an array would probably be a better bet. If the method is returning multiple unrelated values then it's doing too much.
dsimcha
+2  A: 

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.

Software.Developer
+3  A: 

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.

MikeP
Good to know, thanks.
Richard Hein
A: 

I often use nullable types when returning value types plus an indicator of success rather than returning a bool and using an out parameter for the value type. I even wrap the TryParse method so that it returns a nullable.

Out parameters are bad also because they must use local variables or fields. You can't easily refactor your code to use properties.

It's almost always best to create a custom class/struct, use tuples or nullable types.

Enigmativity
+1  A: 

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.

kekekela