Apparantly, they're "confusing". Is that seriously the reason? Can you think of any others?
views:
533answers:
10Have 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.
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.)
ref/out also don't work with "Func" delegates, so these style APIs are less composable/reusable with some other APIs that use delegates.
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.
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.
Isn't code complexity reason enough? Compare:
int myValue;
ReadFromSomewhere(ref myValue);
To:
int myValue = ReadFromSomewhere();
You can fill an object with the values you want to return and just return the object instead of creating ref and out values.
But it's sometimes easier and I think as good to just use ref/out because now you have to declare a new class just for passing a couple values.
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.