I have been playing with type inference in C# and I have read this thread. As stated in the thread, type inference does not work for generic delegates (when you pass a method to this delegate parameter without any explicit casting) like Func, Action and etc. Then I would like to try LINQ operators like SelectMany with .net Func classes instead of lambda expressions in order to see the result. However, it was not result I expected.
I created a test class named L1 which contains a list of strings in order to use (flatten) in SelectMany. In addition to that I created a test method in order to pass instead of Func type parameter.
public class L1
{
private L1() {}
public L1(string m)
{
Isim = m;
numbers = new List<string> { "1", "2", "3", "4", "5" };
}
public List<string> numbers;
public string Isim { get; private set; }
}
private static IEnumerable<int> a(L1 k)
{
return Enumerable.Empty<int>();
}
When I created an extension method like the one below, C# compiler cannot inference the type of the generic parameters.
public static void Test<T1, T2>(this L1 l, Func<T1, IEnumerable<T2>> a)
{
}
(new L1("test")).Test(a);
It gives 'error CS0411: The type arguments for method 'EnumSand.Test(L1, Func>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.' as I expexted.
However, when I use this method a in LINQ SelectMany extension method, compiler does not give any error and it works.
L1[] l1 = new L1[5] {
new L1("one"), new L1("two"),
new L1("three"), new L1("four"),
new L1("five")
};
var slack = l1.SelectMany(a);
foreach (var t in slack)
{
Console.WriteLine(t);
}
So, what is the difference between these cases and how it is possible in SelectMany to make a good type inference?