Search code examples
c#.netparametersdefaultc#-7.0

How can I specify default values for method parameters in c#7 tuples?


In C#, you can define default parameters as described here. I was playing around with tuples and C#7 (using LinqPad with Preferences -> Queries -> Use Roslyn assemblies turned on) as follows:

void Main()
{   
    var result=AddTuples((1, 2),  (3, 4));
    Console.WriteLine($"Result is: {result}");
}

(int x, int y) AddTuples((int x, int y) a,  (int x, int y) b)
{
    return (a.x + b.x,  a.y + b.y);
}

This works fine, it shows the sum of a and b:

Result is: (4, 6)

Now I was trying to modify AddTuples to have default parameters, but somehow I couldn't figure out how. What I tried is something like:

(int x, int y) AddTuples2((int x, int y) a = (0, 0),  (int x, int y) b = (0, 0))
{
    return (a.x + b.x,  a.y + b.y);
}

But I am getting the error message:

CS1736 Default parameter value for 'a' must be a compile-time constant

CS1736 Default parameter value for 'b' must be a compile-time constant

(try it online with DotNetFiddle)

What am I doing wrong?


Update

Thank you for the great answers provided, I've learned a lot. Let me wrap up: To have default values for tuple parameters, there are 3 possible options:

  1. The old fashioned way: Overloading the method, provide defaults in method body. Disadvantage: If you have more than 2 tuples, overloading becomes cumbersome.
  2. Use nullable tuples, provide defaults in method body.
  3. Use tuple's default values
  4. Use a params array to allow more than 2 tuples in the method's parameters, provide defaults in method body

Note: Options 1., 2. and 4. allow to specify any desired default value, while option 3. is limited to the default values provided by the default keyword.


Solution

  • a and b are not constants. Everything that creates a new instance (whether it is a struct or a class) is not considered a constant, and method signatures only allow constants as default values.

    That said, there is no way to default tuples from the method signature, you have to create a separate method.

    The only way out seems to be using nullable arguments:

    (int x, int y) AddTuples2((int x, int y)? a = null, (int x, int y)? b = null)
    {
        (int x, int y) aNN = a ?? (0,0);
        (int x, int y) bNN = b ?? (0,0);
        return (aNN.x + bNN.x, aNN.y + bNN.y);
    }