2017-06-13 88 views
1

我已经写了返回IEnumerable<T>yield return的方法使用像这样:为什么Visual Studio认为我的“yield return”方法返回一个动态对象?

public IEnumerable<Row> ConvertExcelToRows(IExcelDataReader reader) 
{ 
    while (reader.Read()) 
    { 
     var row = new Row(); 
     // do some work. No dynamic objects here whatsoever 
     yield return row; 
    } 
} 

当我消费我的方法和使用LINQ扩展方法遵循它,Visual Studio中显示的返回值是dynamic类型:

enter image description here

下面是相关的代码导致该症状:

dynamic data = JsonConvert.DeserializeObject(jsonContent); 
using (var stream = await DownloadFile(data.docUrl.ToString())) 
using (var excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream)) 
{ 
    var rows = ConvertExcelToRows(excelReader).ToList<Row>(); 
} 

上面的屏幕快照中的rows的类型是dynamic,它应该是List<Row>

为什么会发生这种情况,我该如何解决?

(请注意:就是一个类我写了这一切基本属性,没有什么动态。)

密钥更新:在改善上面的截图中的过程中,我已经改变了的声明excelReadervarIExcelDataReader这解决了我的问题

当我改回var时,我看到推断出的excelReader类型确实是具有传染性的dynamic

仍然喜欢解释为什么我的方法的动态输入参数会“感染”输出的类型。

+4

'动态'由[某种令人毛骨悚然,地狱般的传染原理]操作(https://blogs.msdn.microsoft.com/ericlippert/2012/11/08/dynamic-contagion-part-two/)。任何步骤,或刷它,[成为](http://static.tvtropes.org/pmwiki/pub/images/invasion-of-the-body-snatchers-78_5124.jpg)。一旦你打开了一个门户网站进入后期绑定区,编译器就开始变得神经质和偏执狂。 –

+2

您需要定义代码中的_everything_。告诉我们'rows'变量的类型,'excelReader'变量的类型,你的“做些什么工作”的代码与返回值有关。根据我们可以做出的假设,它应该可以正常工作,但是你没有给我们一个理由相信你。 –

+1

上游的东西是'动态'。你需要找出什么。 –

回答

5

dynamiccontagion principle操作。如果表达式中有任何内容是dynamic,那么编译器在编译时就不能保证可能会出现什么 - 所以出现的内容也被认为是dynamic。当类型可能在运行时任意更改时,编译器可以执行的静态分析有一个限制。

因此,如果有什么出来你的表情是dynamic,你没有把结果赋值给一个明确dynamic变量,则是因为一些dynamic一定是。如果你没有给该方法显式调用什么dynamic,那么你给它的东西一定是在其他地方“感染”了。

上游的某个方法的参数,您称为该方法的对象或表达式中的某个术语为dynamic。你需要找出什么。

一个明显的候选人是excelReader:它来自哪里,以及在哪里对象从何而来?你给这个方法的参数是什么(如果有的话),你从哪里得到它们?

患者零在那里。

+0

现货。 Patient Zero是'data.docUrl.ToString()'。通过更改为“(字符串)data.docUrl”修复。很惊讶地发现''dynamic'上的'ToString()'被推断为'dynamic'而不是'string'。 – urig

+1

'动态'上的'ToString()'完全可以。一旦对象是“动态”,就不会执行正常的静态分析。 –

+1

@urig OMG JSON。我最好留意一下。所以看起来很方便。诱人美味。 –

相关问题