What is the reason why parameters cannot be optional?

I don't understand why I should declare a variable when calling a method with a parameter out

, although I don't care about the value out

provided by the method.

It seems to me that it is similar to calling a method with a return value bool Foo()

, but does not consume it Foo();

. Having the ability to mark a parameter out

as optional will make my code cleaner or save the API developer from overloading without a parameter out

for that method.

So, what is the reason why parameters cannot be optional?

+3


source to share


4 answers


I think there is no real reason why this cannot be. Maybe the reason is simple: because it is documented.

As far as I know, there is no compiler magic, which makes it out

special. Have a look at this CIL code:

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       17 (0x11)
  .maxstack  1
  .locals init ([0] int32 y)
  IL_0000:  nop
  IL_0001:  ldloca.s   y
  IL_0003:  call       void ConsoleApplication15.Program::X(int32&)
  IL_0008:  nop
  IL_0009:  ldloc.0
  IL_000a:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_000f:  nop
  IL_0010:  ret
} // end of method Program::Main

.method public hidebysig static void  X([out] int32& i) cil managed
{
  // Code size       6 (0x6)
  .maxstack  8
  IL_0000:  nop
  IL_0001:  ldarg.0
  IL_0002:  ldc.i4.s   10
  IL_0004:  stind.i4
  IL_0005:  ret
} // end of method Program::X

      

Produced from this method:



public static void X(out int i)
{
    i = 10;
}

static void Main(string[] args)
{
    int y;
    X(out y);

    Console.WriteLine(y);
}

      

As you can see, the variable is allocated in the calling method, and the value is passed "by reference". Specifying a default value for the out

"just" parameter breaks the check to see if the value has been set (because it is already).

Also, as Damien_The_Unbeliever commented , it might just be a function skipped / missed in the original assembly of optional parameters as it out

already exists.

+3


source


Out parameters are compiler. In the CLR, nothing is called a parameter out

. This is indeed the parameter ref

that is passed to the method.

The difference is that the compiler will make sure the value is assigned before the method exits. What is it.

So when you need to call a method with a ref / out parameter, you don't need a value, but a variable / field reference.



For additional options, the C # compiler will pass a default value when calling methods, but you can't here; you need a link.

If the compiler needs to support this function, it should create a variable for you, pass it by reference, and ignore the result. As you can see, this is an ugly thing and therefore we don't have this feature.

+1


source


The "current" C # compiler (pre-Roslyn) is quite complex, and at Microsoft they tried to modify it only if absolutely necessary. Optional parameters, if needed for COM interoperability, that's why they added them. The optional parameters may not have been needed.

We can hope that with Roslyn the compiler will advance faster and we will introduce a new age of syntax bloat :-)

Someone made a feature request for this on Roslyn github: https://github.com/dotnet/roslyn/issues/186

0


source


I think there are two levels in this discussion. Technical level and functional level.

On a technical level, the question should be: is it possible / can it be done? In this case, the answer is YES. It is very easy for the compiler to create a hidden local object and call a method with an optional out parameter with a reference to that hidden local file.

At the functional level, we have to ask ourselves: is this what we really want?

My opinion is: why not? We already ignore the return values ​​when we call the function and nothing with its result. So why shouldn't we allow (automatically) ignore the value coming out of the (optional) outer parameter?

In addition, we may encounter other overloads of this method, but as a state, we already have these conflicts when using options, so there is nothing new.

In the end, it depends on the C # designers. And they must answer these two questions: is it possible and do we want it?

0


source







All Articles