我正在使用Dapper并让它返回动态IEnumerable,如下所示:
var rows = conn.Query("SELECT * FROM T WHERE ID = @id", new { id = tableId });
var row = rows.FirstOrDefault();
此处rows
的类型为IEnumerable<dynamic>
。 IntelliSense说FirstOrDefault()
是可以等待的,并且使用await FirstOrDefault()
。并非所有LINQ查询都显示为等待,但似乎特别是那些单独输出元素的那些。
一旦我使用强类型,这种行为就会消失。
是不是因为.NET无法知道您在运行时接收的类型是否可以接受,因此它允许&#34;允许&#34;它,如果你需要它?但是没有强制执行吗?或者我应该,由于一些动态语言运行时行为,实际上在这里使用await
?
我一直在搜索,但没有在网上找到最小的东西。
答案 0 :(得分:8)
async-await
功能取决于Duck Typing。所以有方法GetAwaiter
(实例或扩展方法)返回实现INotifyCompletion
接口的类型并具有下一个字段的所有内容:
bool IsCompleted { get; }
void|TResult GetResult()
可以等待。
您可以在编译时(从docs)调用动态类型上的任何内容:
在编译时,假定键入为动态的元素支持任何操作。
这就是编译器在编译时没有显示任何警告/错误的原因,但在运行时,您将获得类似于以下内容的异常:
RuntimeBinderException。
'&lt;&gt; f__AnonymousType0'不包含'GetAwaiter'的定义
如果指定显式类型,编译器将搜索方法GetAwaiter
。然后,如果您的强类型不包含它,您将收到编译时错误。
所以,你的问题的答案确实是因为dynamic
的特殊行为。