Why doesn't the C # compiler only allow delegation types in the inverse type when passing a group of methods as a parameter?

Pay attention to the following code:

class Program { static void Foobar() { } static void Test(Action a) { } static void Test(Func<bool> a) { } static void Main(string[] args) { Test(Foobar); } } 

It does not compile on VS2012. The compiler complains that the reference to the Foobar method in the Test(Foobar) ambiguous. This is the error message I get:

 The call is ambiguous between the following methods or properties: 'Program.Test(System.Action)' and 'Program.Test(System.Func<bool>)' 

Now a fix would be to simply drop Foobar into Action to force overload: Test((Action)Foobar) .

But I'm interested in the reason why C # can't figure it out on its own? Why should he think that Func<bool> will be a real overload for the void() function?

I know that you cannot overload a method with another method that differs only in the type of the return value. But this does not seem to be the case. I do not overload Foobar() . Sure, the return value may not be part of the Foobar signature, but why does it matter when it comes to converting from method groups to delegates?

I also know about the problem that the compiler sometimes refuses to throw groups of methods with overloaded methods to certain delegates, even if it can have all the information it needs, but I think this is a different problem (and another error message). Again - Foobar is not overloaded. Only Test() .


Edit: As Matthew noted, the problem is the same as the related question. However, I am not 100% satisfied with the (very good) answer given by Eric Lippert and John Skeet.

In one part of his answer, Eric says:

The principle here is that defining a convertible group of objects requires choosing a method from a group of methods using overload resolution and overload resolution do not consider return types .

Any clue why? It seems to me that the solution to the problem is to precisely change this sentence above, and also consider the type of the return value when choosing methods from the group of methods. The period is over and everyone is happy, no?;)

A practical example of why this ambiguous error sucks is that Task.Run() cannot be used on void() methods of its own class without translation. Therefore, even in some of the MSDN examples I saw, they used Task.Run(() => Foobar()) instead of the much cleaner Task.Run(Foobar) .

+4
source share
1 answer

Since both delegates can be invoked without any parameter:

 Action action = new Action(() => ...); Func<bool> func = new Func<bool>(() => true); action(); func(); // Legal even if you ignore the return value 

The return type is not taken into account to allow overloading.

0
source

Source: https://habr.com/ru/post/1484590/


All Articles