Conditional operator and Comparison Delegate

为君一笑 提交于 2019-12-01 18:21:09

Th error method actually says it all but it’s not quite intuitive. If you use a method name without invoking the method, you are handling a method group. “group”, because a method could be overloaded and the name can indicate any of the overloaded methods.

Now, method groups are convertible implicitly to a delegate with matching signature, this is why your assignment in if works.

So far, so good. However, the conditional operator ?: needs to deduce a common type to which its second and third arguments can be implicitly converted, and it does not consider all conversions for that (this would have diverse problems). It merely looks whether both arguments have the same type, or whether one is implicitly convertible into the other.

This is not the case here: although both arguments are method groups, they are in fact different method groups with distinct types, and you cannot convert one method group into another. Even though both can readily be converted into a delegate, the compiler forbids this usage.

The same is true for other types, by the way:

object = someBool ? "" : New List<Integer>();

also fails to compile, for the same reason. And again, we can make this compile by explicitly casting either of the arguments to a common base type:

object = someBool ? (object) "" : New List<Integer>();

If you have an expression like your CompareByKey, it doesn't have any specific .Net type, but has a special type “method group”. That's because you could have several methods called CompareByKey and it's unclear which one do you want (and it works exactly the same even if you have only one method). Also, it's unclear what delegate type do you want, e.g. Comparison<KeyValuePair<int, string>> or Func<KeyValuePair<int, string>, int>.

What can you do with method groups? You can use them to explicitly create a delegate (new Comparison<KeyValuePair<int, string>>(CompareByKey)) and they are also implicitly convertible to delegates. This is why your if version works.

So, what does that have to do with your problem? When you have a conditional operator, the compiler has to figure out the type of the whole expression and it can't use the type of the variable you assign it to (that's not how type inference works in C#). And since both of the expressions are method groups and method groups are treated as different types with no implicit conversions between each other, the type of the whole expression cannot be determined. Which is why you get the error.

You already found a fix: either don't use conditional operator or specify the type of one of the operands explicitly by using a cast (or delegate constructor).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!