无法从用法中推断出开放泛型类型参数
Open generic type arguments cannot be inferred from the usage
在这个问题中,当提到编译器时,我实际上指的是Roslyn编译器。使用IntelliSense时出现问题,推测是同一个编译器
出于演示目的和完整性,使用了以下 类(使用 Visual Studio 2015 with 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> { }
看下面的扩展方法:
public static void FooBar<T1, T2>(
this Helper<IEnumerable<T1>> helper,
Expression<Func<T1, IEnumerable<T2>>> expression) { ... }
编译器能够在像这样消费时推断它:
Helper<IEnumerable<B>> helper = ...;
helper.FooBar(l => l.C); //T1 is B and T2 is C
还要看这个重载的扩展方法:
public static void FooBar<T1, T2, T3>(
this Helper<T1> helper,
Expression<Func<T1, IEnumerable<T2>>> expression1,
Expression<Func<T2, IEnumerable<T3>>> expression2) { ... }
编译器无法在输入时推断出T1
:
Helper<A> helper = ...;
helper.FooBar(l => l. //compiler/IntelliSense cannot infer that T1 is A
这个截图示例将更多地描述我的意思 无法推断:
此外,当我将鼠标悬停在扩展方法上时,我收到此错误消息(我已将 <
和 >
字符替换为 [
和 ]
,因为 Whosebug 无法格式化引号中的那些 ):
The type arguments for method 'FooBar[T1,T2](this Helper[IEnumerable[T1]], Expression[Func[T1, IEnumerable[T2]]])' cannot be inferred
from the usage. Try specifying the type arguments explicitly.
但是当像这样手动完成它时:
helper.FooBar(l => l.B, l => l.C); //compiler infers that T1 is A, T2 is B and T3 is C
编译器很高兴。
为什么 compiler/IntelliSense( 或 Visual Studio 的自动完成功能)无法找出 T1
并希望我指定当我开始输入时明确输入参数?
注意 如果我在我的示例中到处省略 IEnumerable<>
,编译器可以在键入时愉快地推断出所有内容。
在您手动输入 l => l.B
后,编译器也会很高兴。然后它知道 T1
是 A
,因此您可以在 IntelliSense 的帮助下用 表达最后一个参数 。
如果我没理解错的话,在 VS2013:
中一切都按预期工作
您的第一个案例:
你的第二个案例:
我开始输入 l.
,IntelliSense 显示 l
有一个 属性 B
可以使用。因此,如果我是对的,它 在 VS2013 中 正确推断 而它 在 VS2015,那肯定是VS2015 IntelliSense 的bug,可以反馈给微软
我发现你的问题很有趣,因为我使用的是 VS 2015,所以我想我也可以试试。我得到了和你一样的错误,所以我猜它可能是一个 VS 错误,因为在其他版本中它工作正常。
这是我的错误:
而且我在 CTRL + SPACE 上也得到 没有建议。
编辑:
可以看到类似的错误。
所以,既然在旧版本的 VS 中这是有效的,那么这就是为什么它可以被认为是一个错误的原因。
正如我所说,我有 (And here 是错误报告)
它与表达式或 IEnumerable 无关。
这是一个简化的例子
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; }
}
}
我刚刚注意到,如果您从方法中删除第三个参数,它就会起作用!!!
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; }
}
}
因此,如果您非常幸运,您也许可以通过调整参数来修复当前示例。
不行就等MS修复吧...
在这个问题中,当提到编译器时,我实际上指的是Roslyn编译器。使用IntelliSense时出现问题,推测是同一个编译器
出于演示目的和完整性,使用了以下 类(使用 Visual Studio 2015 with 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> { }
看下面的扩展方法:
public static void FooBar<T1, T2>(
this Helper<IEnumerable<T1>> helper,
Expression<Func<T1, IEnumerable<T2>>> expression) { ... }
编译器能够在像这样消费时推断它:
Helper<IEnumerable<B>> helper = ...;
helper.FooBar(l => l.C); //T1 is B and T2 is C
还要看这个重载的扩展方法:
public static void FooBar<T1, T2, T3>(
this Helper<T1> helper,
Expression<Func<T1, IEnumerable<T2>>> expression1,
Expression<Func<T2, IEnumerable<T3>>> expression2) { ... }
编译器无法在输入时推断出T1
:
Helper<A> helper = ...;
helper.FooBar(l => l. //compiler/IntelliSense cannot infer that T1 is A
这个截图示例将更多地描述我的意思 无法推断:
此外,当我将鼠标悬停在扩展方法上时,我收到此错误消息(我已将 <
和 >
字符替换为 [
和 ]
,因为 Whosebug 无法格式化引号中的那些 ):
The type arguments for method 'FooBar[T1,T2](this Helper[IEnumerable[T1]], Expression[Func[T1, IEnumerable[T2]]])' cannot be inferred from the usage. Try specifying the type arguments explicitly.
但是当像这样手动完成它时:
helper.FooBar(l => l.B, l => l.C); //compiler infers that T1 is A, T2 is B and T3 is C
编译器很高兴。
为什么 compiler/IntelliSense( 或 Visual Studio 的自动完成功能)无法找出 T1
并希望我指定当我开始输入时明确输入参数?
注意 如果我在我的示例中到处省略 IEnumerable<>
,编译器可以在键入时愉快地推断出所有内容。
在您手动输入 l => l.B
后,编译器也会很高兴。然后它知道 T1
是 A
,因此您可以在 IntelliSense 的帮助下用 表达最后一个参数 。
如果我没理解错的话,在 VS2013:
中一切都按预期工作您的第一个案例:
你的第二个案例:
我开始输入 l.
,IntelliSense 显示 l
有一个 属性 B
可以使用。因此,如果我是对的,它 在 VS2013 中 正确推断 而它 在 VS2015,那肯定是VS2015 IntelliSense 的bug,可以反馈给微软
我发现你的问题很有趣,因为我使用的是 VS 2015,所以我想我也可以试试。我得到了和你一样的错误,所以我猜它可能是一个 VS 错误,因为在其他版本中它工作正常。
这是我的错误:
而且我在 CTRL + SPACE 上也得到 没有建议。
编辑:
可以看到类似的错误
所以,既然在旧版本的 VS 中这是有效的,那么这就是为什么它可以被认为是一个错误的原因。
正如我所说,我有
它与表达式或 IEnumerable 无关。
这是一个简化的例子
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; }
}
}
我刚刚注意到,如果您从方法中删除第三个参数,它就会起作用!!!
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; }
}
}
因此,如果您非常幸运,您也许可以通过调整参数来修复当前示例。
不行就等MS修复吧...