|
Unless I am perfeclty sure that the language of the project will be the same, it has not to interface with DLLs and the compiler won't change.
Having wrestled with tons of marshalling between different architectures and ways of doing things of different ages I prefer returning a struct .
BTW if during deep developement I need to add a parameter I can do it with a single change instead of changing the function signature and all the references or adding a new function which will incorporate the old code and making the old function a layer on top.
GCS d-- s-/++ a- C++++ U+++ P- L+@ E-- W++ N+ o+ K- w+++ O? M-- V? PS+ PE- Y+ PGP t+ 5? X R+++ tv-- b+(+++) DI+++ D++ G e++ h--- ++>+++ y+++* Weapons extension: ma- k++ F+2 X
|
|
|
|
|
To me, the best use of ref and out is to manipulate arrays of structs avoiding a copy and avoiding doing things like
array[i].Key = 1;
array[i].Value = 2;
About the TryParse, I really think doing it with nullable types (or returning null to class-types) does a better job.
Edit: Also, because of how variance works and the inner details of how out is implemented, out parameters can't be an "out T". This makes it impossible to declare a bool TryGetValue(TKey key, out TValue) having TValue to be "out TValue".
So, even if you want a TryGetValue to have an out parameter, it is best declared as:
TValue TryGetValue(TKey key, out bool found);
This way, you can declare TValue itself as out.
|
|
|
|
|
If you use them wisely then they can serve a purpose. But try to keep their usage to a minimum.
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C.A.R. Hoare
Home | LinkedIn | Google+ | Twitter
|
|
|
|
|
I would use not more than one reference or out parameter per function.
If there is a need for multiple ref- or out parameters this is a clear sign that there is a class missing:
private bool ReadCustomerData(int pkCustomer, out string CustomerCode, out string CustomerName, out CustType type)
{
}
private CustomerInfo ReadCustomerData(int pkCustomer)
{
}
private void CleanupLine(ref string line)
{
}
private string CleanupLine(string line)
{
}
|
|
|
|
|
I gave up the C# and Microsoft game a several years ago and have since moved to Java, ObjC and Swift. I would assume though this could be a better question if it just discussed the general idea of passing by reference?
|
|
|
|
|
Although I can't recall an instance of ever writing them in my own code
|
|
|
|
|
I've written them when developing code that matches a previously designed usage pattern. For instance, the TryParse design pattern returns a Boolean for success/failure and the out parameter receives the parsed data on success.
|
|
|
|
|
Out parameters are useful when you want the same operation to behave differently in various situations. I found them useful in my own binary trees where there are use cases to throw an exception or not throw an exception when a key/value is not there. To me, the real purpose of using Out is to eek out minor performance gains since you don't include any Exception data on the stack.
The real reason that Out is in C# can likely be attributed to support for many different Win32 API calls that return HRESULT as-well-as creating a C-style struct containing information requested by the caller.
if (Object.DividedByZero == true) { Universe.Implode(); }
Meus ratio ex fortis machina. Simplicitatis de formae ac munus. -Foothill, 2016
|
|
|
|
|
--Mr. Obvious
They used to be useful, with a bitter aftertaste.
Now there are better alternatives.
|
|
|
|
|
Words of wisdom
|
|
|
|
|
We could instead have something like this:
(bool success, int parsedValue) = Int32.Parse("123");
But I hear that some do not like tuples.
Latest Article - Code Review - What You Can Learn From a Single Line of Code
Learning to code with python is like learning to swim with those little arm floaties. It gives you undeserved confidence and will eventually drown you. - DangerBunny
Artificial intelligence is the only remedy for natural stupidity. - CDP1802
|
|
|
|
|
But then, don't you have to add a separate if line after that to do the "ok" test? For me, it's clearer to read with a bool return and an out parameter.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Prior to C# 7, wouldn't you need two lines in both cases?
int value;
if (int.TryParse(someText, out value)) ...
vs:
(bool success, int value) = int.TryParse(someText);
if (success) ...
Of course, C#7 makes the first one cleaner:
if (int.TryParse(someText, out int value)) ...
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Richard Deeming wrote: Of course, C#7 makes the first one cleaner:
if (int.TryParse(someText, out int value)) ...
Exactly.
|
|
|
|
|
Marc Clifton wrote: But I hear that some do not like tuples.
In my case, only because I'd rather use a discriminated union (like F#'s Option or Result ) for the return type...
I know, I know, I'm an outlier...
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Tuples are fantastic, been using them in Python for ages.
One morning I shot an elephant in my pajamas. How he got in my pajamas, I don't know.
|
|
|
|
|
IMHO, there are far greater atrocities to deal with than "out" parameters.
|
|
|
|
|
It just avoids the question, though: we can declare any non-pleasing use as "unwise.
a.k.a. "Good: the way I use them."
|
|
|
|
|
peterchen wrote: a.k.a. "Good: the way I use them."
Wrong - they are Good the way I use them
Espen Harlinn
Chief Architect - Powel AS
Projects promoting programming in "natural language" are intrinsically doomed to fail. Edsger W.Dijkstra
|
|
|
|
|
|
Of course - as long as you use them as I say!
|
|
|
|
|
I'm sure there are legitimate uses for "outs" but the place most C# devs have to use them (and the only time that they ever seem to crop up in my code) is for various TryParse() methods, which violate the SRP by both validating and parsing.
To my mind, they really should have been implemented as IsParseable() and Parse().
98.4% of statistics are made up on the spot.
|
|
|
|
|
TryParse returns a bool, because sometimes, you need to know if it parsed correctly or not, but you also need the value that is parsed. So, how "else" would you do that? You could use a Tuple but I actually hate tuples and use them very sparingly.
|
|
|
|
|
I'd kind of hope that we always want to test the return value!
Whilst I don't see it as the crime of the century, TryParse() does do two things (hence its need for an "out" as well as a return value).
As I suggested, it should, strictly speaking, be split into two methods that do one thing each e.g.
bool IsParseable(string)
T Parse(string)
as opposed to:
bool TryParse(string, out T)
The return value does not relate to the entire purpose of the method and aside from not following SOLID principles, this also has an effect on code readability. For a start we have a method with a verbal name and a boolean value - "bool DoSomething()" is inherently misleading, a bool should answer a question not describe an action.
Also, the fact that we tend to be looking for a negative in the return value means that we tend to wind up with a rather inverted logic.
I would suggest that:
if (int.IsParseable(someString))
someProperty = int.Parse(someString);
else
would be much more readable than:
if (!int.TryParse(someString, out someProperty))
98.4% of statistics are made up on the spot.
|
|
|
|
|
if (int.IsParseable(someString))
someProperty = int.Parse(someString);
This could lead an interesting discussion, whether this code can be optimized by JIT-compiler to make a parsing only once. But this is C#, who cares?
|
|
|
|