0
votes

I'm not sure, why calling Map2 gives me

The type arguments for method 'Program.Map2(object, Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Here is the code...

void Test()
{
    var test1 = Map1(1, MapIntToString);
    var test2 = Map2(1, MapIntToString);
}

To Map1<From, To>(From value, Func<From, To> mapFunc) => mapFunc(value);
To Map2<From, To>(object value, Func<From, To> mapFunc) => mapFunc((From)value);

string MapIntToString(int value) => Convert.ToString(value);

This is very simplified example. I need to convert some lists of DTOs to Models (and back), but it should be same case...

2
In Map1, you easily let it infer the From is int since that's the type of the first parameter. In Map2, it doesn't know where to start with FromDamien_The_Unbeliever
Also, bear in mind that at the call site for Map1 and Map2, the compiler has no information about how those methods are implemented - it can only work from the method signatures - and even if it could do deeper inspection, the cast is in the wrong direction.Damien_The_Unbeliever

2 Answers

1
votes

Because you have defined the parameter of type object while the method MapIntToString has first parameter of type int. So the compiler is not able to figure out that the parameter passed to mapFunc for Map2 i.e object value is currently holding value of type int. Your code will be translated to something like below if we visualize it when will be resolved at run-time but at first place it is not compiling as it's not able to resolve the generic type From:

Map2<Object, String>(object value, Func<object, String> mapFunc) => mapFunc((object)value);

So, obviously this wouldn't work as your method expects parameter of type int not object.

You need to be explicit about the type parameters in this case as Compiler is not smart enough to know that the object value is currently holding value of type int in it.

0
votes

Being explicit works:

var test2 = Map2<int, string>(1, MapIntToString);

or

var test2 = Map2(1, (Func<int, string>)MapIntToString);

I'm afraid I cannot point to the reason why it does not work implicitly. My personal guess would be that MapIntToString is not a single method, but a Method Group (with one member) that can be converted to a Func<int, string> without problems, but that conversion is not used in resolving generics.