我在运行时在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。答案 0 :(得分:2)
Enumerable.First()
是Enumerable中定义的扩展方法,而不是List
的方法。实际上,它们是静态方法,通过编译器魔术使看起来像实例方法一样。编译器知道将扩展方法调用转换为它们的静态等价物,即Enumerable.First()
变为Enumerable.First(someEnumerable,...)
。
当你动态调用First()
时,它被称为动态对象上的一个方法。运行时搜索对象的动态方法,而不能知道你想要调用一些静态方法。
如果直接以静态形式调用扩展方法,即if (!Enumerable.First(unlocked)) ...