为什么动态类型的linq'First()'有时会在运行时失败?

时间:2016-07-08 15:16:41

标签: c# linq dapper

我在运行时在c#.NET 4.6.1项目中有这种奇怪的linq行为。 我正在重复使用动态类型来保存来自Dapper查询的结果集(此处未显示)。

请考虑以下代码:

...
IEnumerable<dynamic> resultSet = await dataSource.GetUserInfos(unlockingUserId, applicationName);
...

传入的结果集包含一行,其中包含许多不同的列。

稍后在代码中,我将使用另一个数据库查询的结果分配resultSet对象:

resultSet = await dataSource.ReleaseLock(userId, unlockingUserId, itemId, sessionId);

这次从服务器返回的行仍然包含一行但只有一个名为boolean的列,比如说'success'。

以下代码:

...
if (resultSet.First().success != true)

因以下运行时异常而失败:

  

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException:   'System.Collections.Generic.List'不包含   'First'的定义

使用其他动态对象保存结果时没有问题:

IEnumerable<dynamic> unlocked = await dataSource.ReleaseLock(userId, unlockingUserId, itemId, sessionId);

这一次,以下代码:

...
if (unlocked.First().success != true)

工作正常。

编辑:这是我的错误。 GetUserInfos返回动态而不是IEnumerable。

1 个答案:

答案 0 :(得分:2)

Enumerable.First()是Enumerable中定义的扩展方法,而不是List的方法。实际上,它们是静态方法,通过编译器魔术使看起来像实例方法一样。编译器知道将扩展方法调用转换为它们的静态等价物,即Enumerable.First()变为Enumerable.First(someEnumerable,...)

当你动态调用First()时,它被称为动态对象上的一个方法。运行时搜索对象的动态方法,而不能知道你想要调用一些静态方法。

如果直接以静态形式调用扩展方法,即if (!Enumerable.First(unlocked)) ...

,您可以使用扩展方法