Why it is necessary for the out parameter to be assigned to before it leaves the current method?
Can someone please elaborate me what is going inside the shell? Thanks in advance.
Why it is necessary for the out parameter to be assigned to before it leaves the current method?
Think of an out parameter as an extra return value. Just as you can't return from a non-void method without specifying the return value, you can't return from a method with an out parameter without setting a value for the parameter.
This in turn allows the argument for an out parameter to be definitely assigned after the method has completed, because it will definitely have been given a value by the method:
int value;
Foo(out value);
Console.WriteLine(value); // This is fine
Because it is designed in this way.That is the difference between out and ref parameters.By declaring an argument as out, the method guarantees that it will set the value of the argument.By ref, it doesn't have to.If you don't want an out use ref.
Related
Currently when trying to do something in a method that takes an out parameter, I need to assign the value of the out parameter in the method body, e.g.
public static void TryDoSomething(int value, out bool itWorkerd)
{
itWorkerd = true;
if (someFavourableCondition)
{
// if I didn't assign itWorked variable before this point,
// I get an error: "Parameter itWorked must be assigned upon exit.
return;
}
// try to do thing
itWorkerd = // success of attempt to do thing
}
I'd like to be able to set a default value of the itWorked parameter so I don't have to arbitrarily set the value in the body of the method.
public static void TryDoSomething(int value, out bool itWorkerd = true)
{
if (someFavourableCondition)
{
// itWorked was already assigned with a default value
// so no compile errors.
return;
}
// try to do thing
itWorkerd = // success of attempt to do thing
}
Why is it not possible to assign a default value for an out parameter?
Default values are available for parameters passed by value. The parameter is still passed to the function but if the code omits the parameter, the compiler supplies the missing value.
Your proposed feature is quite different. Instead of the caller omitting to pass the value, you propose to allow the implementer of the function to omit setting the value. So, this is a quite different feature. Why was it not implemented? Here are some possible reasons:
Nobody thought to implement this feature.
The designers considered the feature and rejected it as not useful enough to be worth the cost of implementing.
The designers considered the feature and rejected it as being confusing because it uses similar syntax to default value parameters, but has a quite different meaning.
I appreciate this isn't exactly answering the original question, but I'm unable to contribute to the comments. I had the same question myself so found myself here.
Since C#7 now allows out parameters to effectively be variable declarations in the calling scope, assigning a default value would be useful.
Consider the following simple method:
private void ResolveStatusName(string statusName, out string statusCode)
{
statusCode = "";
if (statusName != "Any")
{
statusCode = statusName.Length > 1
? statusName.Substring(0, 1)
: statusName;
}
}
It felt intuitive to modify it like so:
private void ResolveStatusName(string statusName, out string statusCode = "")
{
if (statusName != "Any")
{
statusCode = statusName.Length > 1
? statusName.Substring(0, 1)
: statusName;
}
}
The intention was to not only declare the statusCode value, but also define it's default value, but the compiler does not allow it.
Even if it allowed you to give a default value like that, it would still require you to assign value for the parameter for all returns. So your default value will be overridden.
Default parameter values are the default value for parameters passed in to the method. You have to specify a variable to pass for an out parameter so that you can get the returned value.
Your first example, in a way, has a default, set at the beginning of the method.
The out method parameter keyword on a method parameter causes a method to refer to the same variable that was passed into the method. Any changes made to the parameter in the method will be reflected in that variable when control passes back to the calling method.
Declaring an out method is useful when you want a method to return multiple values. A method that uses an out parameter can still return a value. A method can have more than one out parameter.
To use an out parameter, the argument must explicitly be passed to the method as an out argument. The value of an out argument will not be passed to the out parameter.
A variable passed as an out argument need not be initialized. However, the out parameter must be assigned a value before the method returns.
Compiler will not allow you to use out parameter as default parameter because it is violating its use case. if you don't pass it to function you cannot use its value at calling function.
if you could call below function like TryDoSomething(123) then there is no use of out parameter because you will not be able to use value of itWorked
public static void TryDoSomething(int value, out bool itWorkerd = true)
{
if (someFavourableCondition)
{
// itWorked was already assigned with a default value
// so no compile errors.
return;
}
// try to do thing
itWorkerd = // success of attempt to do thing
}
If you have two calls to a method that uses 'out' or 'ref', and you want to avoid to split the method up in two, if one of the calls is not using these parameters, an elegant solution to avoid the warning from the compiler that "the value is not being used" (or something similar), is to use something like this:
method("hi", out _);
A method parameter declared with 'out' cannot have its value assigned by the caller. So a default value cannot be assigned during the call, either.
Also, you must always initialize an 'out' parameter in the method's body before using the parameter or returning from the method. This would overwrite any default value.
This is the whole point with the 'out' modifier. If you want a different behavior, check out the 'ref' and 'in' modifiers.
I am pretty new in C# (I came from Java) and I have the following doubt.
In a class I have the declarationf of this method:
public List<DataModel.MaliciousCode.MaliciousSmall> getList(DataModel.MaliciousCode.MaliciousSmall model, out int totalRecords)
{
.............................................
.............................................
.............................................
}
My doubt is related to the out keyword in the paramether list.
Reading the official documentation I have understand that this parameter is passed by reference (and that it could be not initialized).
So what exactly means? It means that in C# I have pointers?
out means that when this method will be called, the parameter totalRecords will be assigned some value from the method, and that value will be available to the caller.
out parameter modifier (C# Reference)
The out keyword causes arguments to be passed by reference. This is
like the ref keyword, except that ref requires that the variable be
initialized before it is passed. To use an out parameter, both the
method definition and the calling method must explicitly use the out
keyword.
For example, if you call your method like:
int totalRecords; //just declaration no initialization
var list = getList(new MaliciousSmall(), out totalRecords);
Console.WriteLine(totalRecords);// value from method.
at the end of method call, totalRecords will be assigned some value inside the method. It is mandatory for the method getList to assign/initialize some value to totalRecords. If it is not assigned any value in the method, a compile time error would occur. That is the reason why out parameters may or many not be initialized before using in method call.
inside your method, out int totalRecords must be assigned to any correct value depending on its type before the methods returned.
Even the totalRecords might be assigned to a value before calling this method (not encouraged), but the totalRecords still must be assigned to a value before it come out from method and other variable cannot do any value calculations or operations on it before it is assigned to any value, and this is different with other parameter modifiers such as ref.
For me, I might use the method return value as indication of method process, and out variable on other results that must come out from the method but the initialized value outside scope of the method can be ignored. safely handle multiple return values with out
Refer to accepted answer of this post, obvious difference is "You can say ++ on a pointer, but not on a ref or out." and ref is very closed to pointers but not out.
When we checked the Generated CIL Code difference between ref , out and pointers in C#, we can see this.
I'm new to C# and I'm not sure I understand the use of parameterized methods. Below I have added some code that I have been given in a task that I'm going to develop. It's for a simple GUI with some text boxes asking for a name and a price.
The first line of code calls the method and the boolean variable inputOk expects a true or false value and the out parameter will also "return" some values?
In the second line of code, I guess, despite the "return" of name and price I also need to have a return true or false to get the first line of code to work? Just want to be sure I understand it. And since I can reach the input value from the text boxes like txtName.Text, I don't need to add this value when I call the methods? Thanks!
bool inputOk = ReadAndValidateInput(out customerName, out seatPrice);
private bool ReadAndValidateInput(out string name, out double price)
Simply put, yes you are right on all counts, but I do think you might need to brush up on your terminology; the return value of a method is what's returned while the stuff that goes in the brackets are parameters; and when you call the the method they are called arguments.
For some more detail.
It's best to start with the second line.
The boolean is returned from the method. The name and price parameters are guaranteed to be modified by the method (because they are out, if they were ref then they might be modified); and, while yes they can be thought of as additional return values, in reality the mechanism is completely different: they are just called output parameters.
Edit - concerning 'output parameters'
An output parameter can still used also to pass in values (so really they are input/output). The method that receives the argument must then ensure that it then writes to it (because it's out).
End-edit
If that method is written inside a form class, which owns a textbox then, yes, you can simply use the textbox variable without having to pass it in; because the method is an 'instance method' (as opposed to a static, which has no this) and the variable belongs to the same instance of the form.
On the first line, yes - inputOk receives the boolean return value from calling the method - passing customerName and seatPrice as output arguments. After the method returns, assuming no exception occurs, inputOk will be set to the return value of the method; and the two arguments will receive the values set by the ReadAndValidateInput method call.
Imagine situation, where ReadAndValidateInput would not only validate input, but do some calculations and return other value - discount for example. That's where you would need out parameter
double discount = 0;
if(ReadAndValidateInput(customerName, seatPrice, out discount))
{
//do something with discount. You know that input was valid
}
else
{ // do not touch discount. User has not entered valid values
}
You do not need out parameters if method being called does not change values or does not generate new values other than return ones. You are right - original values can be accessed from calling code.
You normally should call it as:
string name;
double price;
bool inputOk = ReadAndValidateInput(out customerName, out seatPrice);
All three variables will get assigned values within ReadAndValidateInput.
In C++ it is not possible to return multiple values and the 'out' keyword is then an alternative to use.
However, it is best to avoid it if possible. You also can make two additional get functions to return the customer name and seat price.
Actually I am doing a list as a reference parameter as follows:
public static List ListMethod(List result)
I saw some people doing in this way too:
public static void ListMethod(ref List result)
If I'm not wrong, "my" method also takes the list as reference parameter, and you should be able to use it just the same way as "other" does in his method.
But it seems more "clean" to me that you enter a parameter, do something with it and return it in the methods return value.
Any good arguments for or against one method or the other?
It's likely that you don't need to use ref - but there is a difference.
Usually when I see people using ref for reference type parameters, it's because they don't understand how parameter passing works. But if your method has something like this:
result = new List();
...
then in the first case the caller won't see the change, whereas in the second case the caller's variable will be changed to refer to the new object.
See my article on parameter passing for a lot more detail.
No, your method does not use a ref parameter. The default is pass by value.
The difference is, that your method can just modify the contents of your list but not the reference the parameter result points to.
Whats the best approach? It depends on what your method is supposed to do.
When your method modifies the list or returns new data you should use the return value.
Its much better to understand what your code does than using a ref parameter.
Another benefit of return values is the ability to use method chaining.
You can write code like this which passes the list parameter from one method to another:
ListMethod1(list).ListMethod2(list)...
If you're just returning a List, you should always use the first one as it shows that intention.
The version with ref tells me that I can start out with a list, and your method will modify the list I sent in, or even change it with another one. If that is your intention, do that.
But if the method allways returns a new list, use a return value instead of a ref parameter.
A note on the side: you could use out instead of ref to show your intentions of returning a new list, but this is only a good practice if you're using the return value for something else.
One thing special about ref Parameter here is that - "A variable passed with ref must be assigned value first.". So if you want to make it strict for the calling method to assign value before the call you can probably use ref Parameters.
I'm implementing a TryParse(string s, Out object result) method.
If the parse fails, I would like not to touch the out parameter so any previous result will remain intact.
But VS2k8 won't let me. I have to set the value of the out object no matter what.
Should I just put result = result for the sake of pleasing the compiler? Am I missing something?
Assign null (or default(T) more generally). You must assign a value, that's what 'out' means.
Your suggestion of result = result won't work, because it's an out parameter - it's not definitely assigned to start with, so you can't read its value until you've assigned a value to it.
result = null;
is definitely the right way to go for an object out parameter. Basically use default(T) for whatever type T you've got. (The default operator is useful in generic methods - for non-generic code I'd normally just use null, 0, whatever.)
EDIT: Based on the comment from Boris, it may be worth elaborating on the difference between a ref parameter and an out parameter:
Out parameters
Don't have to be definitely assigned by the caller
Are treated as "not definitely assigned" at the start of the method (you can't read the value without assigning it first, just like a local variable)
Have to be definitely assigned (by the method) before the method terminates normally (i.e. before it returns; it can throw an exception without assigning a value to the parameter)
Ref parameters
Do have to be definitely assigned by the caller
Are treated as "definitely assigned" at the start of the method (so you can read the value without assigning it first)
Don't have to be assigned to within the method (i.e. you can leave the parameter with its original value)
result = null;
Just put some default value. For example the Int32.TryParse method puts zero.
You could use ref instead of out if you don't want to assign a value, although this must then be initialised by the caller.
You could throw an exception before the code that is supposed to set result.