请往下看以获取重要的更新内容!
我有一些像这样的代码:
void Test(IEnumerable x)
{
var dynX = x.Cast<dynamic>();
var result = dynX.Select(_ => _.Text);
}
在一个针对.NET 4.5的现有库项目中,VS2015的智能感知会在Text
部分下划线,并抱怨:“object”不包含“Text”的定义...
确实,编译失败了。
error CS1061:“object”不包含“Text”的定义,也找不到接受类型为“object”的第一个参数的扩展方法“Text”(是否缺少使用指令或程序集引用?)
这个消息总是说“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/新编译器版本在解决扩展方法时存在严重的错误。
以下内容与主题关系不大,主要是关于误导性错误消息的。 我决定保留它,以免让评论变得混乱。
更糟糕的是,即使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追踪器上得到跟踪。
更改为
Func<dynamic, TResult> selector`时,我设法在VS2015上编译它。 - Ringil