为方法的委托参数键入推断

时间:2016-03-31 21:45:39

标签: c# .net linq generics type-inference

我一直在使用C#中的类型推断,我已阅读this thread。如线程中所述,类型推断不适用于泛型委托(当您将方法传递给此委托参数而没有任何显式转换时),如Func,Action等。然后我想尝试使用.net Func等SelectMany的LINQ运算符类而不是lambda表达式,以便查看结果。但是,这不是我预期的结果。

我创建了一个名为L1的测试类,它包含一个字符串列表,以便在SelectMany中使用(展平)。除此之外,我创建了一个测试方法,以便传递而不是Func类型参数。

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>();
}

当我创建如下所示的扩展方法时,C#编译器无法推断通用参数的类型。

public static void Test<T1, T2>(this L1 l, Func<T1, IEnumerable<T2>> a)
{
}

(new L1("test")).Test(a);

它给出了&#39; 错误CS0411:方法的类型参数&#39; EnumSand.Test(L1,Func&gt;)&#39;无法从使用中推断出来。尝试明确指定类型参数。&#39;因为我被驱逐了。

但是,当我在LINQ SelectMany扩展方法中使用此方法 a 时,编译器不会给出任何错误并且它可以正常工作。

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);
}

那么,这些案例之间有什么区别,以及SelectMany如何进行良好的类型推断呢?

1 个答案:

答案 0 :(得分:2)

问题在于:

init_printing(latex_printer=YourSubclass().doprint)

T2绑定到public static void Test<T1, T2>(this L1 l, Func<T1, IEnumerable<T2>> a) ,但int可能是任何东西,这就是无法推断的原因。

您可以将第二个参数更改为T1并完全删除Func<L1, IEnmuerable<T2>>或将T1更改为this L1

编辑: 如果您有以下方法,请考虑这种情况:

this T1

您现在可以说private static IEnumerable<int> a(L1 k) { return Enumerable.Empty<int>(); } private static IEnumerable<int> a(string k) { return Enumerable.Empty<int>(); } 使用哪种a方法吗?

相关问题