我已经编写了一个使用IEnumerable<T>
返回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
类型:
以下是导致症状的相关代码:
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>
。
为什么会发生这种情况,我该如何解决?
(请注意Row
只是我写的一个类。它是所有原始属性,没有动态)
关键更新:在改进上述屏幕截图的过程中,我已将excelReader
的声明从var
更改为IExcelDataReader
。 这解决了我的问题。
当我改回var
时,我发现excelReader
的推断类型确实是具有传染性的dynamic
。
仍然喜欢解释为什么我的方法的动态输入参数会感染&#34;感染&#34;输出的类型。
答案 0 :(得分:5)
dynamic
由contagion principle运营。如果表达式中的任何内容都是dynamic
,那么编译器在编译时不能保证可能出现的内容 - 所以出来的内容也被视为dynamic
。当类型可能在运行时任意改变时,编译器可以执行静态分析的限制。
因此,如果您的表达式中出现的内容为dynamic
并且您没有将结果分配给明确的dynamic
变量,那么这是因为某些内容dynamic
必须进来。如果你没有明确地给这个方法调用任何东西dynamic
,那么你给它的东西一定是被感染了#34;别处。
上游的某个内容,方法的参数,调用方法的对象或表达式中的术语dynamic
。你需要找出什么。
一个显而易见的候选人是excelReader
:它来自哪里, 对象来自哪里?你给这个方法的参数是什么(如果有的话),你从哪里获得它们?
零点病人在那里。