0

I'm trying to define a new subroutine which takes in a dictionary as an optional parameter with the default value as an empty dictionary as well as two non-optional strings.

public void findPath(string start, string end,
    Dictionary<string, object[]> nodeInfo = new Dictionary<string, object[]>())
{}

I keep getting an error when passing the dictionary that the "Default parameter value for 'nodeInfo' most be compile-time constant". How do I fix this? Thanks

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188
spchee
  • 61
  • 3
  • 1
    As far as I know, this is a limitation of C#. You can try to circumvent this by having the parameter default to `null` and using the ?? operator or a null check, see [this question this seems to be a duplicate of](https://stackoverflow.com/questions/18740421/default-parameter-for-value-must-be-a-compile-time-constant) – the default. Feb 10 '19 at 14:20
  • 1
    From [here](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/const): "**Constants can be numbers, Boolean values, strings, or a null reference.** Don’t create a constant to represent information that you expect to change at any time. **For example, don’t use a constant field to store the price of a service, a product version number, or the brand name of a company.** These values can change over time, and because compilers propagate constants, other code compiled with your libraries will have to be recompiled to see the changes." – grooveplex Feb 10 '19 at 14:21

1 Answers1

3

You can't, not directly. Default values for parameters must be compile-time constants.

You've got a couple of options.

The first is to use a sentinel default value, like null:

public void findPath(string start, string end,
    Dictionary<string, object[]> nodeInfo = null)
{
    if (nodeInfo == null)
        nodeInfo = new Dictionary<string, object[]>();
}

The second is to use method overloading:

public void findPath(string start, string end)
{
    findPath(start, end, new Dictionary<string, object[]>();
}

public void findPath(string start, string end,
    Dictionary<string, object[]> nodeInfo)
{
}

They need to be compile-time constants because they're baked into the places where the method is called. For example, if you used null as a sentinel value and wrote this:

findPath("start", "end");

It gets compiled to this:

findPath("start", "end", null);

See the MSDN documentation on what is allowed as a default parameter value:

  • a constant expression;
  • an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct;
  • an expression of the form default(ValType), where ValType is a value type.

Constant expressions:

Constants can be numbers, Boolean values, strings, or a null reference

canton7
  • 37,633
  • 3
  • 64
  • 77