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



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

请考虑以下代码:

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

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

在代码的后面部分,我将为结果集对象分配另一个数据库查询的结果:

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

这一次,从服务器返回的行仍然包含一行,但只有一个名为"成功"的布尔列。

以下代码:

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

失败,出现以下运行时异常:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: "System.Collections.Generic.List"不包含 "第一"的定义

使用另一个动态对象来保存结果时我没有问题:

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

这次,以下代码:

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

工作正常。

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

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

但是,当您动态调用First()时,它会作为动态对象上的方法调用。运行时搜索对象的动态方法,并且不知道是否要调用某个静态方法。

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

相关内容

  • 没有找到相关文章