无法从使用中推断出打开泛型类型参数

Qua*_*ive 18 .net c# generics roslyn visual-studio-2015

在这个问题中,当提到编译器时,我实际上指的是Roslyn编译器.使用IntelliSense时出现问题,IntelliSense被认为是相同的编译器.

出于演示目的和完整性,使用以下类(使用Visual Studio 2015与C#6.0和.NET 4.6.1):

public class A
{
    public IEnumerable<B> B { get; set; }
}
public class B
{
    public IEnumerable<C> C { get; set; }
}
public class C { }
public class Helper<T> { }
Run Code Online (Sandbox Code Playgroud)

请看以下扩展方法:

public static void FooBar<T1, T2>(
    this Helper<IEnumerable<T1>> helper,
    Expression<Func<T1, IEnumerable<T2>>> expression) { ... }
Run Code Online (Sandbox Code Playgroud)

编译器能够在消耗时推断它,如下所示:

Helper<IEnumerable<B>> helper = ...;
helper.FooBar(l => l.C); //T1 is B and T2 is C
Run Code Online (Sandbox Code Playgroud)

还有这个重载的扩展方法:

public static void FooBar<T1, T2, T3>(
    this Helper<T1> helper,
    Expression<Func<T1, IEnumerable<T2>>> expression1,
    Expression<Func<T2, IEnumerable<T3>>> expression2) { ... }
Run Code Online (Sandbox Code Playgroud)

编译器是能够推断出T1这样打字时它:

Helper<A> helper = ...;
helper.FooBar(l => l. //compiler/IntelliSense cannot infer that T1 is A
Run Code Online (Sandbox Code Playgroud)

这个截图示例将描述更多我无法推断的含义:
在此输入图像描述

当我用鼠标悬停在扩展方法上时,我收到此错误消息(我已经分别用和替换了<>字符,因为StackOverflow无法格式化引号中的那些[]):

方法'FooBar [T1,T2](此Helper [IEnumerable [T1]],Expression [Func [T1,IEnumerable [T2]]])'的类型参数不能从用法中推断出来.尝试显式指定类型参数.

但是当像这样手动完成它时:

helper.FooBar(l => l.B, l => l.C); //compiler infers that T1 is A, T2 is B and T3 is C
Run Code Online (Sandbox Code Playgroud)

编译器很高兴.

为什么编译器/ IntelliSense(或Visual Studio的自动完成功能)无法找到T1并希望我在开始键入时明确指定类型参数?

请注意,如果我IEnumerable<>在示例中省略了所有内容,编译器可以在键入时愉快地推断所有内容.
手动输入后,编译器也很高兴l => l.B.那时它才知道T1A,这样你就可以表达的最后一个参数智能感知的帮助.

Iva*_*nko 4

如果我理解正确的话, VS2013中的一切都按我的预期工作:

您的第一个案例:

你的第二个案例:

我开始输入l.,IntelliSense 向我显示有一个可以使用的l属性。B因此,如果我是对的并且它在VS2013中推断正确,而在VS2015中没有推断,那么这绝对是VS2015 IntelliSense 中的一个错误,可以向 Microsoft 报告。