0

I was writing some logging code, and I had to invoke either of two methods with the same signature:

void Error(string, Exception)
void Warn(string, Exception)

I decided to approach this with functional programming instead of an if/else. I have a bool wasHandled to determine which method to invoke. I tried:

Action<string, Exception> logAction = wasHandled ? _logger.Warn : _logger.Error;

But the compiler / intellisense complained with:

Cannot choose method from method group. Did you intend to invoke the method?

Instead, I had to write it like this:

var logAction = wasHandled ? new Action<string, Exception>(_logger.Warn) : _logger.Error;

I get the bonus of var but I really hate that I have to explicitly invoke new Action.....

Why does the former not work?

MarioDS
  • 12,895
  • 15
  • 65
  • 121
  • 2
    [The answer to this question might help](http://stackoverflow.com/questions/6015747/why-does-funcbool-test-value-f-f-not-compile) It's not identical, but it's a similar issue. – Matthew Watson May 29 '15 at 08:20
  • @MatthewWatson Sadly the question was changed midway (from `var` to `Func<>`) so the responses are mixed. – xanatos May 29 '15 at 08:23
  • Note that you can even write `var logAction = wasHandled ? (Action)_logger.Warn : _logger.Error;`, so using the cast instead of the constructor (no real difference in generated code) – xanatos May 29 '15 at 08:23
  • 1
    @xanatos The response marked as the answer is correct (and answers both cases) – Matthew Watson May 29 '15 at 08:24
  • @MatthewWatson Yes... But the response is split in two... and in truth it doesn't explain why `Func value = F` works while `Func value = true ? F : F` doesn't. The answer seems to handwave it a little – xanatos May 29 '15 at 08:28
  • 1
    This seems to be better: http://stackoverflow.com/a/26369348/613130 Both answer in this one go in the same direction, and they are quite easy to comprehend. – xanatos May 29 '15 at 08:29
  • Same question here: http://stackoverflow.com/q/5186394/613130 (but the question was more complex... Robinson's answer nails it well. – xanatos May 29 '15 at 08:32
  • 1
    BTW, I wouldn't characterise this as "functional programming", especially seeing as `Warn()` and `Error()` are likely to have side-effects (outputting a message) – Matthew Watson May 29 '15 at 08:35
  • I would concur with @MatthewWatson: what you are doing here is not functional programming. You are using the service locator pattern to ask for a function, thus the function that contains this line of code is no longer a pure function. – David Arno May 29 '15 at 08:51

1 Answers1

0

This doesn't work cause the type of _logger.Warn is the method group.

Unlike many functional languages, C# has method (function) overloading, so MethodName can mean any of methods with different signatures but with the same name.

Perhaps the C# compiler could handle this situation by the special way, but it doesn't.

Mark Shevchenko
  • 7,937
  • 1
  • 25
  • 29