Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't C#'s overload resolution work between Func<T,T> and Action<T>? [duplicate]

Tags:

c#

linq

So, a fairly common extension method for IEnumerable, Run:

public static IEnumerable<T> Run<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (var item in source)
    {
        action(item);
        yield return item;
    }
}

When I try to use that with, for instance, DbSet.Add:

invoice.Items.Run(db.InvoiceItems.Add);
// NB: Add method signature is
// public T Add(T item) { ... }

... the compiler complains that it has the wrong return type, because it is expecting a void method. So, add an overload for Run that takes a Func instead of Action:

public static IEnumerable<T> Run<T>(this IEnumerable<T> source, Func<T, T> action)
{
    return source.Select(action).ToList().AsEnumerable();
}

And now the compiler complains that "The call is ambiguous between the following methods..."

So my question is, how can the Action overload of the Run method cause ambiguity when it is not valid for the method group?

like image 794
Mark Rendle Avatar asked Jun 27 '12 11:06

Mark Rendle


People also ask

Why there is no string in C?

Both Java and Python have the concept of a "string", C does not have the concept of a "string". C has character arrays which can come in "read only" or manipulatable. A character array is a sequence of contiguous characters with a unique sentinel character at the end (normally a NULL terminator '\0' ).

What does C++ have that C doesnt?

C++ was developed by Bjarne Stroustrup in 1979. C does no support polymorphism, encapsulation, and inheritance which means that C does not support object oriented programming. C++ supports polymorphism, encapsulation, and inheritance because it is an object oriented programming language.

Why C has no exception handling?

As such, C programming does not provide direct support for error handling but being a system programming language, it provides you access at lower level in the form of return values. Most of the C or even Unix function calls return -1 or NULL in case of any error and set an error code errno.

Does C have a print function?

Print Function in C, C++, and Python Print function is used to display content on the screen.


1 Answers

This has already been explained by Eric and Jon in answers to this question. Long story short - this is how C# compiler works; precisely, when dealing with method group conversion deciding what delegate it will be converted to utilizes overload resolution, which does not take return types in account:

The principle here is that determining method group convertibility requires selecting a method from a method group using overload resolution, and overload resolution does not consider return types.

In your example compiler sees both Action<T> and Func<T, T> as best match for Add. This adds up to two possible choices, and since it requires one - appropriate error is issued.

like image 176
k.m Avatar answered Sep 20 '22 15:09

k.m