¿Por qué linq 'First ()' en tipo dinámico a veces falla en tiempo de ejecución?

c# dapper linq

Pregunta

Tengo este extraño comportamiento de linq en tiempo de ejecución en el proyecto ac # .NET 4.6.1. Estoy reutilizando un tipo dinámico para mantener el conjunto de resultados proveniente de las consultas de Dapper (no se muestran aquí).

Considera el siguiente código:

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

El conjunto de resultados entrantes contiene una fila con muchas columnas diferentes.

Más adelante en el código, estoy asignando el objeto resultSet con el resultado de otra consulta de base de datos:

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

Esta vez, la fila devuelta por el servidor todavía contiene una fila pero solo una columna booleana llamada, digamos 'éxito'.

El siguiente código:

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

falla con la siguiente excepción de tiempo de ejecución:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.Collections.Generic.List' no contiene una definición para 'Primero'

No tengo ningún problema cuando uso otro objeto dinámico para mantener los resultados:

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

Esta vez, el siguiente código:

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

Funciona bien.

EDITAR: Fue un error de mi parte. GetUserInfos devolvía dinámico en lugar de IEnumerable.

Respuesta popular

Enumerable.First() es un método de extensión definido en Enumerable, no en un método de List . En realidad, son métodos estáticos que están diseñados para parecerse a los métodos de instancia a través de la magia del compilador. El compilador sabe traducir las llamadas al método de extensión a su equivalente estático, es decir, Enumerable.First() convierte en Enumerable.First(someEnumerable,...) .

Sin embargo, cuando llama a First() dinámicamente, se llama como un método en el objeto dinámico. El motor de ejecución busca los métodos dinámicos del objeto y no puede saber que usted quería llamar a algún método estático en su lugar.

Puede usar métodos de extensión si los llama en su forma estática directamente, es decir, if (!Enumerable.First(unlocked)) ...



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué