5

So I have the following function. I would like it to have a standard parameter value but I can't get it to work as it needs to be a compile time constant. I know I can set it to null but I want it to be a specific function.

    private void func(Func<List<int>, bool> eval = _ => true)
    {
        var b = eval();
    }

Is it even possible to something like this?

krjw
  • 4,070
  • 1
  • 24
  • 49
  • 2
    Nope, lambdas cannot be constant, that's just a CLR limitation, see https://stackoverflow.com/questions/19198037/declare-lambda-expression-as-a-class-constant-field for details. A workaround would be to have your optional parameter default to `null` and just do `if (eval == null) eval = ...` first thing in your code. – Heinzi Aug 07 '19 at 14:22

3 Answers3

6

Since default parameters must be compile time constants, you can't provide an easy default function quite like you want. You can work around this, though, using null as you pointed out.

private void func(Func<List<int>, bool> eval = null)
{
    eval = eval ?? (_ => true);
    // Do things.
}

This will assign your default implementation if null is passed, or the function is called without any parameters.

In modern versions of C#, you can use the null assignment operator, ??=.

This would look something like this:

eval ??= _ => true;

Jonathon Chase
  • 9,396
  • 21
  • 39
2

An alternative to the answer from @JonathonChase is to use an overload:

private void func() => func(_ => true);
1

You can't assign anything other than null as the default parameter to any reference type other than string. Func<List<int>, bool> is a reference type.

So just do what you want to do as a default in the function:

private void func(Func<List<int>, bool> eval = null)
{
    if (eval == null)
    {
        //do some default thing
    }
    else 
         eval.Invoke(new List<int>());
}
Tim Rutter
  • 4,549
  • 3
  • 23
  • 47