TraumaPony
TraumaPony

Reputation: 10794

Why does the .Net framework guidelines recommend that you don't use ref/out arguments?

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

Upvotes: 9

Views: 1924

Answers (10)

Paul Mendoza
Paul Mendoza

Reputation: 5787

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.

Upvotes: -1

pero
pero

Reputation: 4259

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

Upvotes: 0

Joshua
Joshua

Reputation: 43280

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.

Upvotes: 0

user23117
user23117

Reputation: 1892

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.

Upvotes: 1

Cristian Libardo
Cristian Libardo

Reputation: 9258

Isn't code complexity reason enough? Compare:

int myValue;
ReadFromSomewhere(ref myValue);

To:

int myValue = ReadFromSomewhere();

Upvotes: -2

Sklivvz
Sklivvz

Reputation: 31133

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.

Upvotes: 5

Samuel Kim
Samuel Kim

Reputation: 3733

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.

Upvotes: 3

Brian
Brian

Reputation: 118865

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

Upvotes: 1

Brian
Brian

Reputation: 118865

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.)

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1500645

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.

Upvotes: 14

Related Questions