Question

Apparently, they're "confusing". Is that seriously the reason? Can you think of any others?

Was it helpful?

Solution

Have you seen how many developers don't really understand ref/out?

I use them where they're really necessary, but not otherwise. They're usually only useful if you want to effectively return two or more values - in which case it's worth at least thinking about whether there's a way of making the method only do one thing instead. Sometimes using ref/out is the most appropriate approach - the various TryParse methods etc.

OTHER TIPS

In my opinion, they are considered a code smell because in general there is a much better option: returning an object.

If you notice, in the .NET library they are only used in some special cases, namely tryparse-like scenarios where:

  • returning a class would mean boxing a value type
  • the contract of the method requires it to be fast, and so boxing/unboxing is not a viable option.

ref/out automatically means mutability, and functional programming with immutable values is all the rage these days. Try inserting a call to Dictionary.TryGetValue into a LINQ query. The API requires declaring variables and ruins any 'fluency' in the API.

That's not to say this is "the reason", but it is an example of "a reason".

(See also

http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!181.entry

for commentary on how functional languages deal with such APIs.)

Confusing is probably the best reason. Confusing means decreased maintainability and increased likelyhood on introducing subtle bugs. I see them in a similar view to the "goto" control flow statement. While it is not inherently bad on its own accord, it has lead to many many impossible to read / understand programs over the decades.

Stay away from anything that can make your code more confusing then it needs to be.

Having said that, those keywords exist probably because the framework developers saw need for such things. Use them if there is no suitable workaround, but avoid them when you can.

ref/out also don't work with "Func" delegates, so these style APIs are less composable/reusable with some other APIs that use delegates.

Just a thought, I find ref/out to be useful when the arguments capture the state of execution in target method rather than capturing returned data. Consider a scenario when you want to get an error message from a service that returns Customer object.

Customer GetCustomerById(int id, out string errorMessage);

If this method fails, you would probably return null Customer object or throw an exception. However, if I want to know the cause of error (validation? database?), I would use out argument. errorMessage argument here has nothing to do with data, simply used to capture what's wrong with the method execution.

Personally if I have a method that is expected to return two or more essential data/values, I would rethink the design of my code.

The reason I was told is the 1.0 GC had problems when ref/out was used. The GC in 2.0 (and probably not 1.1 either) doesn't have those problems so I would normally assume it is a now non-useful legacy.

@TraumaPony It would be fine if you give us an source (URL or something) to this .NET framework guidlines.

You should be returning objects is probably the most likely reason that they suggest not using ref or out.

"ref" really only needs to be used when passing scalar values but I see people use it often for objects that are being passed by reference anyways.

Isn't code complexity reason enough? Compare:

int myValue;
ReadFromSomewhere(ref myValue);

To:

int myValue = ReadFromSomewhere();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top