Is it possible to use optional/default parameters

2020-02-11 17:36发布

Is there a way to use optional arguments (default parameters) with lambda expressions in c#? I have read through the documentation but can find nothing to say one way or the other.

To illustrate, I can define simple method that uses an optional argument to supply a default value like so:

void MyMethod(string arg = "default-value")
{ 
    Console.WriteLine(arg);
}

What I want to know is if I am able to do the same thing using a lambda expression.

// gives a syntax error
Action<string> MyMethod = (arg = "default") => Console.WriteLine(arg);

I can work in an optional parameter with a default value using a delegate, but this seems a bit clumsy.

delegate void MyDelegate(string arg = "default");
MyDelegate MyMethod = arg => Console.WriteLine(arg);

Alternatively I could check the parameter in the lambda body, something like...

 Action<string> MyMethod = (arg) => Console.WriteLine(string.IsNullOrEmpty(arg) ?
                                    "default" :
                                    arg);

But again this seems a bit clumsy.

Is it possible to use optional parameters to set a default value in a lambda expression in c#?

2条回答
太酷不给撩
2楼-- · 2020-02-11 17:46

The lambda will match whatever the signature of the delegate it's assigned to is; without being assigned to a delegate a lambda cannot compile.

If the delegate contains optional arguments then the use of that delegate can optionally supply arguments. If the delegate doesn't, then the use of that delegate cannot omit any arguments.

While the Action and Func delegates are very handy, and can represent most signatures, they can't represent any signature with optional arguments; you must use another delegate definition for that.

Remeber, Action and Func aren't particularly special, they're just two delegates that everyone uses so that they don't need to worry about creating their own for every little thing.

查看更多
ら.Afraid
3楼-- · 2020-02-11 18:04

No. The caller (the code invoking the delegate) doesn't "see" the lambda expression, so it doesn't make sense to specify the default parameter there. All the caller sees is the delegate. In your case, for example, the calling code only knows about Action<string> - how is the compiler meant to know to supply the default value that's specified by the lambda expression?

As an example of how things get tricky, imagine if this were viable. Then consider this code:

Action<string> action;
if (DateTime.Today.Day > 10)
{
    action = (string arg = "boo") => Console.WriteLine(arg); 
}
else
{
    action = (string arg = "hiss") => Console.WriteLine(arg);
}
action(); // What would the compiler do here?

Bear in mind that the argument is provided by the compiler at the call site - so what should it do with the final line?

It's a bit like having an interface and an implementation - if you have a default parameter on an interface, that's fine; if you only have it on the implementation, then only callers who know the specific implementation will see it. In the case of lambda expressions, there's really no visible implementation for the caller to use: there's just the delegate signature.

查看更多
登录 后发表回答