5

Scratching my head. What's wrong with the following statement?

var EncFunc = (encrypt ? Encryption.Encrypt : Encryption.Decrypt);

encrypt is bool, both of the functions Encryption.Encrypt and Encryption.Decrypt have the same type Func<string, string>, but it tells me that:

CS0173 Type of conditional expression cannot be determined because there is no implicit conversion between 'method group' and 'method group'

I have already gone through this and this, but can't understand why compiler cannot determine the type of these 2 functions.

N.B. I know this can be fixed with explicit casting. I'm more interested in understanding the "why" part.

Community
  • 1
  • 1
dotNET
  • 33,414
  • 24
  • 162
  • 251
  • May [this](https://msdn.microsoft.com/en-us/library/hb47kt2f.aspx) help? But I guess you already read it. So I guess [this](http://stackoverflow.com/questions/2215745/conditional-operator-cannot-cast-implicitly/2215959#2215959) is the possible duplicate question and answer. – ckruczek Mar 02 '17 at 06:07
  • @ckruczek: Thanks. That was a good read. But it doesn't address this situation. The type information is flowing out of the RHS, not into it, because the LHS is inferred. – dotNET Mar 02 '17 at 06:21
  • I think the problem can be simply put as, you cannot do this "var encFunc = Encryption.Encrypt;", but you can do this "Func encFunc = Encryption.Encrypt;". Why is that, unfortunately I'm not sure... I would also like to know why it has troubles detecting adequate implicit conversion to delegate. – Mario Z Mar 02 '17 at 06:27
  • @MarioZ: Very nice find. I'd like to highlight though that there is no *conversion* involved in the first case you mentioned. We are not specifying the type of our variable. Inference should determine whatever type is appropriate for the RHS. – dotNET Mar 02 '17 at 06:35
  • I'm not sure what do you mean "there is no conversion", ok maybe conversion is a wrong word, how about delegate creation. After all that is what we're doing here, we're not assigning method but rather a delegate. Now after some thinking, this seems reasonable behavior, because we could actually have couple of other delegates which have the same signature, so there is no way for the compiler to know exactly what delegate we want. – Mario Z Mar 02 '17 at 06:37
  • @MarioZ: Thanks a lot. Your first comment led me in the right direction and I found [this gem](http://stackoverflow.com/questions/4965576/why-cant-an-anonymous-method-be-assigned-to-var). Again Eric Lippert to the rescue :). Your second comment is basically what he's explaining there in great detail. – dotNET Mar 02 '17 at 06:49

1 Answers1

10

I think the following explains why the compiler is having difficulties with this. Let's say we have:

string MyMethod() { return ""; }

We cannot assign that method to var, in other words we cannot use this:

// Not valid.
var method = MyMethod;

That is because there could be any number of delegates that could be used, for example:

delegate string MyDelegate();

With this we now have two options and it seems that it would be wrong for the compiler to assume one over the other:

// Valid.
Func<string> myFunc = MyMethod;

// Valid.
MyDelegate myDel = MyMethod;

EDIT: For the sake of completion I'm adding a reference to this (it was mentioned by OP in the comments).

Community
  • 1
  • 1
Mario Z
  • 4,328
  • 2
  • 24
  • 38