【发布时间】:2015-07-29 12:14:21
【问题描述】:
请进一步查看重大更新!
我有一些这样的代码:
void Test(IEnumerable x)
{
var dynX = x.Cast<dynamic>();
var result = dynX.Select(_ => _.Text);
}
在针对 .NET 4.5 的现有库项目中。 VS2015 的 IntelliSense 强调了Text 部分,抱怨:'object' 不包含'Text' 的定义......
果然编译失败了
错误 CS1061:“object”不包含“Text”的定义,并且找不到接受“object”类型的第一个参数的扩展方法“Text”(您是否缺少 using 指令或程序集引用?)
此消息始终显示'object',即使我将演员表更改为.Cast<IAsyncResult>() 或诸如此类。当我悬停 lambda 参数时,工具提示显示它的类型为 IColumn(存在但不相关)。同样,无论我转换为哪种类型。
但是,当我将Select() 方法悬停时,它正确地将参数显示为Func<dynamic, dynamic>。如果我明确指定 lambda 参数类型,它会编译。如果我在Select() 上明确指定类型参数,它也可以工作。
dynamic 的其他 LINQ 用法正在运行。当我将此方法复制到解决方案中的另一个(现有)项目时,它也会编译。当我将它复制到同一个项目中的另一个文件时,它不会编译。
它也可以用 VS2013 编译。
在 Windows 8.1 和 Windows 10 中,我的所有同事也会出现同样的错误。
也许这是类型推断的一些奇怪问题...?
我尝试过但无济于事的事情:
- 创建一个新的 .NET 4.5 库项目并重新添加文件和缺少的引用
- 比较(原始)项目文件——除了元素排序之外没有区别
更新
好吧,我设法创建了一个独立的最小失败示例:
static class Program
{
static void Main(string[] args)
{
IEnumerable x = new object[0];
IEnumerable<dynamic> dynX = x.Cast<dynamic>();
// CS1061 'object' does not contain a definition for 'Text'...
// var tooltip shows IColumn instead of IEnumerable<dynamic>
var result = dynX.Select(_ => _.Text);
}
public static IColumn Select<TResult>(this IColumn source, Func<object, TResult> selector)
{
throw new NotImplementedException();
}
}
public interface IColumn { }
在我看来,这清楚地表明VS2015/新编译器版本在解析扩展方法方面存在严重错误。
以下内容只是松散相关,主要是关于误导性错误消息。我决定保留它,以免让 cmets 感到困惑。
更糟糕的是,即使IEnumerable 和object 都不可能有扩展方法Select(),它们也会失败并出现相同的错误:
// CS1061 'object' does not contain a definition for 'Text'
// var tooltip shows IColumn
var result2 = x.Select(_ => _.Text);
object o = new object();
// CS1061 'object' does not contain a definition for 'Text'
// var tooltip shows IColumn
var result3 = o.Select(_ => _.Text);
附录
此问题现已在 Roslyn bug tracker 上进行跟踪。
【问题讨论】:
-
VS 2010 没有给出任何此类编译时错误!
-
这个项目使用了哪个框架?
-
我设法在 VS2015 中在 4.5.2 上很好地编译了这个方法。和 4.6.
-
@MarcinJuraszek 感谢您的提示,我终于设法创建了一个最小的示例。如果其他人可以对此进行测试并确认这确实是一个错误,我会很高兴。
-
我认为您的问题可能与此有关:github.com/dotnet/roslyn/issues/4160。我在 VS2015 和 VS2013 中测试了您的示例。在 VS2013 中,
result有效,但result2和result3都失败了。在 VS2015 中,它们都失败了,但是我从 var 工具提示中得到了不同的结果。 var 工具提示显示它是object而不是IColumn。当我按照 Roslyn 问题页面上的建议将Func<object, TResult> selector更改为Func<dynamic, TResult> selector时,我设法让它在 VS2015 上编译。
标签: c# dynamic extension-methods visual-studio-2015 type-inference