简体   繁体   English

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

[英]Open generic type arguments cannot be inferred from the usage

In this question, when mentioning the compiler, I'm actually referring to the Roslyn compiler. 在这个问题中,当提到编译器时,我实际上指的是Roslyn编译器。 The problem arises when using IntelliSense , which is presumed to be the same compiler. 使用IntelliSense时出现问题, IntelliSense被认为是相同的编译器。

For demonstration purposes and completeness, the following classes are used ( using Visual Studio 2015 with C# 6.0 and .NET 4.6.1 ): 出于演示目的和完整性,使用以下类( 使用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> { }

Behold the following extension method: 请看以下扩展方法:

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

The compiler is able to infer it while consuming like this: 编译器能够在消耗时推断它,如下所示:

Helper<IEnumerable<B>> helper = ...;
helper.FooBar(l => l.C); //T1 is B and T2 is C

Also behold this overloaded extension method: 还有这个重载的扩展方法:

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

The compiler is NOT able to infer T1 when typing it like this: 编译器不能推断T1像这样,只要当它:

Helper<A> helper = ...;
helper.FooBar(l => l. //compiler/IntelliSense cannot infer that T1 is A

This screenshot example will describe more of what I mean with not able to infer : 这个截图示例将描述更多我无法推断的含义:
在此输入图像描述

Also I'm getting this error message when hovering over the extension method with my mouse ( I've replaced the < and > characters with [ and ] respectively, because StackOverflow cannot format those in a quote ): 当我用鼠标悬停在扩展方法上时,我收到此错误消息( 我已经分别用[]替换了<>字符,因为StackOverflow无法格式化报价中的那些 ):

The type arguments for method 'FooBar[T1,T2](this Helper[IEnumerable[T1]], Expression[Func[T1, IEnumerable[T2]]])' cannot be inferred from the usage. 方法'FooBar [T1,T2](此Helper [IEnumerable [T1]],Expression [Func [T1,IEnumerable [T2]]])'的类型参数不能从用法中推断出来。 Try specifying the type arguments explicitly. 尝试显式指定类型参数。

But when completing it manually like this: 但是当像这样手动完成它时:

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

the compiler is happy. 编译器很高兴。

Why can't the compiler/IntelliSense ( or the autocomplete feature of Visual Studio ) figure out T1 and wants me to specify the type arguments explicitly when I start typing? 为什么编译器/ IntelliSense( 或Visual Studio的自动完成功能 )无法找出T1并希望我在开始输入时明确指定类型参数?

Note that if I omit IEnumerable<> everywhere in my examples, the compiler can happily infer everything while typing. 请注意 ,如果我在示例中省略了IEnumerable<> ,编译器可以在键入时愉快地推断出所有内容。
The compiler is also happy after you manually type in l => lB . 手动输入l => lB后,编译器也很高兴。 It then knows T1 is A , so you can express the last argument with the help of IntelliSense. 然后它知道T1A ,所以你可以表达智能感知的帮助下,最后一个参数。

If I understood you correctly, everything is working as expected for me in VS2013 : 如果我理解正确,在VS2013中一切都按预期工作:

Your first case: 你的第一个案例:

Your second case: 你的第二个案例:

I'm starting to type the l. 我开始打字了l. and IntelliSense shows me that l has a property B that can be used. 和IntelliSense告诉我l有一个可以使用的属性B So if I'm right and it infers correctly in VS2013 whereas it doesn't infer in VS2015 , then it's definitely a bug in VS2015 IntelliSense that can be reported to Microsoft. 所以,如果我是对的,它在VS2013 正确地推断出 ,而不会VS2015 推断 ,那么它肯定在VS2015的智能感知的错误可以报告给微软。

I found your question interesting and since I'm using VS 2015 I thought I could try it too. 我发现你的问题很有趣,因为我正在使用VS 2015,我想我也可以尝试一下。 I got the same error as you did, so i guess it can be a VS bug, since in other versions it is working properly. 我得到了和你一样的错误,所以我猜它可能是一个VS bug,因为在其他版本中它运行正常。

Here is my error: 这是我的错误:

在此输入图像描述

And I also get No suggestions on CTRL + SPACE. 我也对CTRL + SPACE 没有任何建议

EDIT: 编辑:

A similar bug can be seen here . 这里可以看到类似的错误。

So, since in older versions of VS this works, then this is the reason why it can be considered a bug. 所以,因为在旧版本的VS中,这是有效的,所以这就是它被认为是一个bug的原因。

As I said I had the same problem. 正如我所说,我有同样的问题。 (And here is the bug report) 是错误报告)
It is not related to Expressions or IEnumerable. 它与Expressions或IEnumerable无关。
Here is a simplified example 这是一个简化的例子

using System;

namespace ConsoleApplicationExpressionTree
{

    public static class Extentions
    {
        static void Main() { }
        static void AMethod(string[] args)
        {
            SetValue(new Customer(), e => e.Name   /*type here */, "TheName");

        }

        public static void SetValue<TEntity, TProperty>(TEntity instance, Func<TEntity, TProperty> expression, TProperty newValue)
        {

        }
    }
    public class Customer
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

I just noticed that if you remove the 3rd argument from the method it works !!! 我刚刚注意到,如果从方法中删除第三个参数,它就可以了!

using System;

namespace ConsoleApplicationExpressionTree
{

    public static class Extentions
    {
        static void Main() { }
        static void AMethod(string[] args)
        {
            SetValue(new Customer(), e => e.Name   /*type here */);

        }

        public static void SetValue<TEntity, TProperty>(TEntity instance, Func<TEntity, TProperty> expression)
        {

        }
    }
    public class Customer
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

So if you are very lucky you might be able to fix your current example by tweaking your parameters. 因此,如果您非常幸运,您可以通过调整参数来修复当前示例。
If not,you'll just have to wait for MS to fix it... 如果没有,你只需要等待MS修复它......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM