short:
I have a method decimal GetAmount(IThing thing)
. Using things.Sum(GetAmount)
results in a CS0121 error: call is ambiguous between Sum(Func<T, int>)
and Sum(Func<T, int?>)
. Why?
longer:
public interface IThing { }
public class Sample {
public decimal GetAmount(IThing thing) { return 0; }
public decimal Total(IThing[] things) { return things.Sum(GetAmount); }
}
Error CS0121 The call is ambiguous between the following methods or properties:
'Enumerable.Sum<TSource>(IEnumerable<TSource>, Func<TSource, int>)'
and'Enumerable.Sum<TSource>(IEnumerable<TSource>, Func<TSource, int?>)'
I would somewhat understand if the compiler was confused between decimal
and decimal?
or if the compiler couldn't pick any of the many Sum overloads. But why/how did it limit itself to only int
and int?
Btw, VS / R# 'helpfully' highlights passing GetAmount
to .Sum()
as an error and suggests passing an int returning method instead. The compiler doesn't flag this part as a second error. Changing GetAmount
to int GetAmount(IThing thing)
actually does 'solve' the compiler error.
ps. I'm not looking for a solution to the compiler error. I know I can turn GetAmount into Func<IThing, decimal> GetAmount { get; }
or implement Total like things.Sum(thing => GetAmount(thing))
. And as suggested by @IvanStoev, things.Sum(new Func<IThing, decimal>(GetAmount))
works (for me) as well.
You just don't have overload of
.Sum()
where you can pass your method.You right you can do it that way:
thing => GetAmount(thing)
- this part basically will create anonymouse function and.Sum()
got overload for it.One of the other ways to implement it (more obviouse way so you can understand what actually happends) is create func yourself:
Actually i get another compiler error with your code (I use VS 2015).
So I think you get that wired error only becouse precompiler analizer is not perfect.
I did a bit more research and try to compile your code without precompiler from command prompt like this:
And now compiler return right error:
As you see now we got right error with
decimal
type. So wierd compiler error that we get located somewhere in precompiler sources.