21

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?

DaveDev
  • 41,155
  • 72
  • 223
  • 385
  • 1
    Probably because it doesn't change anything for the caller. You're just moving an assignment statement from the first line of your method to the parameter list. A regular default parameter puts an assignment (of sorts) in all of the callers, so it changes external behavior. You're asking for syntactic sugar that adds almost no value. – siride May 29 '14 at 12:38
  • 1
    How do *callers* of methods indicate that they want the default value to apply? Now, having thought about that, how does the caller obtain the value of the `out` parameter after your method is complete? – Damien_The_Unbeliever May 29 '14 at 12:39
  • I think it makes as much sense as being able to ignore a return value - a lot of sense. I guess nobody thought this was important enough (it isn't, I think), or that, as Eric Lippert always says, it is too costly to implement compared to its added value. – zmbq May 29 '14 at 12:40
  • I disagree with your assertion that you must "arbitrarily set the value". You are contracting to provide the caller with a `Boolean` value. There's nothing arbitrary about it. You make a conscious decision about the value and provide it. If you don't know up-front what that value should be, then perhaps you should not be using `out` in this case. – DonBoitnott May 29 '14 at 12:47
  • Related: https://stackoverflow.com/questions/2870544/c-sharp-4-0-optional-out-ref-arguments – nawfal Nov 15 '18 at 15:49

7 Answers7

10

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:

  1. Nobody thought to implement this feature.
  2. The designers considered the feature and rejected it as not useful enough to be worth the cost of implementing.
  3. 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.
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • 4. It might be impossible to implement such a feature because the runtime doesn't know when this method has set the value. Is it set when it gets a different value than the default value? Or is it set also if the `out` parameter gets the default value? The implementer could always forget this side effect. If you consider the `TryParse`-methods, the runtime should have to understand if a method succeeded or failed. It's impossible for custom code. – Tim Schmelter May 17 '17 at 10:14
4

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.

Ben Wesson
  • 589
  • 6
  • 16
  • both methods do something completely different. in the first one you always modify `statusCode` and set it to empty string, `statusCode`is never equal to "Any". in the second one, you set it to empty string if no parameter was submitted - but if you don't pass a parameter, you can't use it later in reference (`out` would be senseless). otherwise, if you thought `statusCode` would be changed then from null to empty string: `statusCode` would still stay null. So in conclusion, both methods are senseless - plus, there's still no reason in your code why the default-value would make any sense. – Matthias Burger Mar 31 '20 at 09:40
0

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.

serdar
  • 1,564
  • 1
  • 20
  • 30
0

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
}
Muhammad Zaighum
  • 560
  • 4
  • 21
  • I don't think asker wants to omit the parameter when calling. I think asker just wants to avoid having to assign a value to the parameter in the body of the function. – David Heffernan May 29 '14 at 15:26
  • The question is why cant an out parameter have a default value... so explained it why – Muhammad Zaighum May 29 '14 at 15:40
  • Not really. The asker does not wish to omit the parameter when calling as you describe. The asker wonders why a completely different feature from default parameter values was not implemented for out parameters. The caller wants to write `TryDoSomething(123, out itWorked)` at the call site. But instead wants the implementation of the function to be able to omit setting the value of `itWorked` and so return a default value in that case. – David Heffernan May 29 '14 at 15:50
0

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.

David Crowell
  • 3,711
  • 21
  • 28
0

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 _);

Andrés Fg
  • 138
  • 1
  • 7
0

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.