Return value of parameterized methods? - c#

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.

Related

Accessing a variable declared in a Form

I'm doing a course on learning C# and the task is to create a small converter using windows forms and use a function to perform the conversion.
At the moment I have been able to do everything through defining a variable in the form and having each different button assign a value to the variable, This works fine at the moment since the conversion is happening within an event when the convert button is pushed. But to complete the task I need the conversion to place outside of the form.
The issue I have is I can't figure out how to access the variable I declared within the form and I don't know how I would return the value into the form once I have created the function.
I'm guessing the function would look something like
public double conversion(string ConvertIn, string ConvertOut, double Value)
{
Value = Double.Parse(ValueEntry.Text);
double Output = (Value / Double.Parse(ConvertIn)) * Double.Parse((ConvertOut));
FinalOutput.Text = Convert.ToString(Output);
{
return Output;
}
return 0;
}
To Convert I need to Take a variable the User enters into a text box then / by a value selected via a button then multiply by another value selected via a button
But as I said I can't figure out how to get the 3 variables that have been declared in the form, or how I would return the value into the form output textbox.
Any help would be greatly appreciated.
From your description, it sounds like you've been assigned a homework assignment, in which you have a specific requirement that this method reside in a class other than your Form subclass.
The most straightforward way to do this would be to have some simple "utility" class where you can put a static method to do this conversion. The method parameter list should allow your Form subclass code to pass the values of interest, and of course the caller will take the return value from the method and assign it to an appropriate member (e.g. FinalOutput.Text).
For example:
static class Util
{
public static string conversion(string ConvertIn, string ConvertOut, string Value)
{
double c1 = double.Parse(ConvertIn),
c2 = double.Parse(ConvertOut),
v = double.Parse(Value);
return ((v / c1) * c2).ToString();
}
}
You might call it like this:
FinalOutput.Text = Util.conversion(ConvertIn.Text, ConvertOut.Text, ValueEntry.Text);
Notes:
Lacking a good, minimal, complete code example, I don't really know how the UI is set up. I can infer the ValueEntry and FinalOutput controls from the little bit of code you did provide, but there's nothing to suggest where the ConvertIn and ConvertOut values should come from, so I've just assumed controls of those same names. I presume given the above example, you'll be able to pass the actual correct values to the method.
If this is in fact a homework assignment, as it appears, you will probably still want to consult with your teacher so that you understand better what the above is doing. StackOverflow is not bad for providing actual code solutions to questions, but it's a lot harder to ensure that a student has actually received the explanatory details that are critical to actually learn the concept of interest. (Besides, without knowing the exact homework assignment details, while the above is certainly working code, it's not necessarily what your teacher actually wanted).

Return value of method is modifying an object passed as a method parameter

I'm in a situation where I am writing a method where the return value directly modifies a class which was used to supply paramaters to the method.
Computer.MatchingPassword = PasswordFinder.Find(Computer.Name, PasswordList)
Does assigning to a property of a passed parameter like this have any hazards?
Technically, your code sample doesn't assign to the parameter, since you passed a property of the Computer object.
In other words, you only gave the function "name", so assigning to a different property of the same object would have no effect.
Now, in the more general case, you are still safe. Even passing the whole object, by the time you assign the return value the method has already completed. Any changes you make won't do anything.
In other words, the following code is functionally equivalent:
string password = PasswordFinder.Find(Computer.Name, PasswordList);
Computer.MatchingPassword = password;
Clearly no problems there. This is true even if it was passed by ref, as again, the method is totally done with the object, so any changes to it won't matter.

Why can't an out parameter have a default value?

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.

When should I use out parameters?

I don't understand when an output parameter should be used, I personally wrap the result in a new type if I need to return more than one type, I find that a lot easier to work with than out.
I have seen method like this,
public void Do(int arg1, int arg2, out int result)
are there any cases where that actually makes sense?
how about TryParse, why not return a ParseResult type? or in the newer framework return a null-able type?
Out is good when you have a TryNNN function and it's clear that the out-parameter will always be set even if the function does not succeed. This allows you rely on the fact that the local variable you declare will be set rather than having to place checks later in your code against null. (A comment below indicates that the parameter could be set to null, so you may want to verify the documentation for the function you're calling to be sure if this is the case or not.) It makes the code a little clearer and easier to read. Another case is when you need to return some data and a status on the condition of the method like:
public bool DoSomething(int arg1, out string result);
In this case the return can indicate if the function succeeded and the result is stored in the out parameter. Admittedly, this example is contrived because you can design a way where the function simply returns a string, but you get the idea.
A disadvantage is that you have to declare a local variable to use them:
string result;
if (DoSomething(5, out result))
UpdateWithResult(result);
Instead of:
UpdateWithResult(DoSomething(5));
However, that may not even be a disadvantage, it depends on the design you're going for. In the case of DateTime, both means (Parse and TryParse) are provided.
I think out is useful for situations where you need to return both a boolean and a value, like TryParse, but it would be nice if the compiler would allow something like this:
bool isValid = int.TryParse("100", out int result = 0);
Well as with most things it depends.
Let us look at the options
you could return whatever you want as the return value of the function
if you want to return multiple values or the function already has a return value, you can either use out params or create a new composite type that exposes all these values as properties
In the case of TryParse, using an out param is efficient - you dont have to create a new type which would be 16B of overhead (on 32b machines) or incur the perf cost of having them garbage collected post the call. TryParse could be called from within a loop for instance - so out params rule here.
For functions that would not be called within a loop (i.e. performance is not a major concern), returning a single composite object might be 'cleaner' (subjective to the beholder). Now with anonymous types and Dynamic typing , it might become even easier.
Note:
out params have some rules that need to be followed i.e. the compiler will ensure that the function does initialize the value before it exits. So TryParse has to set the out param to some value even if parse operation failed
The TryXXX pattern is a good example of when to use out params - Int32.TryParse was introduced coz people complained of the perf hit of catching exceptions to know if parse failed. Also the most likely thing you'd do in case parse succeeded, is to obtain the parsed value - using an out param means you do not have to make another method call to Parse
Years late with an answer, I know.
out (and ref as well) is also really useful if you do not wish your method do instantiate a new object to return. This is very relevant in high-performance systems where you want to achieve sub microsecond performance for your method. instantiating is relatively expensive seen from a memory access perspective.
Definitely, out parameters are intended to be used when you have a method that needs to return more than one value, in the example you posted:
public void Do(int arg1, int arg2, out int result)
It doesn't makes much sense to use an out parameter, since you are only returning one value, and that method could be used better if you remove the out parameter and put a int return value:
public int Do(int arg1, int arg2)
There are some good things about out parameters:
Output parameters are initially considered unassigned.
Every out parameter must be definitely assigned before the method returns, your code will not compile if you miss an assignment.
In conclusion, I basically try use out params in my private API to avoid creating separate types to wrap multiple return values, and on my public API, I only use them on methods that match with the TryParse pattern.
Yes, it does make sense. Take this for example.
String strNum = "-1";
Int32 outNum;
if (Int32.TryParse(strNum, out outNum)) {
// success
}
else {
// fail
}
What could you return if the operation failed in a normal function with a return value? You most certainly could not return -1 to represent a fail, because then there would be no differentiation between the fail-return value and the actual value that was being parsed to begin with. This is why we return a Boolean value to see if it succeeded, and if it did then we have our "return" value safely assigned already.
Creating a type just for returning values sounds little painful to me :-)
First i will have to create a type for returning the value then in the calling method i have assign the value from the returned type to the actual variable that needs it.
Out parameters are simipler to use.
It does annoy me that I can't pass in null to the out parameter for the TryParse functions.
Still, I prefer it in some cases to returning a new type with two pieces of data. Especially when they're unrelated for the most part or one piece is only needed for a single operation a moment after. When I do need to save the resulting value of a TryParse function I really like having an out parameter rather than some random ResultAndValue class that I have to deal with.
If you always create a type, then you can end up with a lot of clutter in your application.
As said here, one typical use case is a TrySomething Method where you want to return a bool as an indicator for success and then the actual value. I also find that a little bit cleaner in an if-statement - all three options roughly have the same LOC anyway.
int myoutvalue;
if(int.TryParse("213",out myoutvalue){
DoSomethingWith(myoutvalue);
}
vs.
ParseResult<int> myoutvalue = int.TryParse("213");
if ( myoutvalue.Success ) {
DoSomethingWith(myoutvalue.Value);
}
vs.
int? myoutvalue = int.TryParse("213");
if(myoutvalue.HasValue){
DoSomethingWith(myoutvalue.Value);
}
As for the "Why not return a Nullable Type": TryParse exists since Framework 1.x, whereas Nullable Types came with 2.0 (As they require Generics). So why unneccessarily break compatibility or start introducing inconsistencies between TryParse on some types? You can always write your own extension Method to duplicate functionality already existing (See Eric Lipperts Post on an unrelated subject that includes some reasoning behind doing/not doing stuff)
Another use case is if you have to return multiple unrelated values, even though if you do that that should trigger an alarm that your method is possibly doing too much. On the other hand, if your Method is something like an expensive database or web service call and you want to cache the result, it may make sense to do that. Sure, you could create a type, but again, that means one more type in your application.
I use out parameters sometimes for readability, when reading the method name is more important than whatever the output of the method is—particularly for methods that execute commands in addition to returning results.
StatusInfo a, b, c;
Initialize(out a);
Validate(a, out b);
Process(b, out c);
vs.
StatusInfo a = Initialize();
StatusInfo b = Validate(a);
StatusInfo c = Process(b);
At least for me, I put a lot of emphasis on the first few characters of each line when I'm scanning. I can easily tell what's going on in the first example after acknowledging that some "StatusInfo" variables are declared. In the second example, the first thing I see is that a bunch of StatusInfo is retrieved. I have to scan a second time to see what kind of effects the methods may have.

What should the out value be set to with an unsuccessfull TryXX() method?

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.

Categories