Why are First () or ElementAt () in dynamic IEnumerable waiting?

I used Dapper and return a dynamic IEnumerable, for example:

var rows = conn.Query("SELECT * FROM T WHERE ID = @id", new { id = tableId }); var row = rows.FirstOrDefault(); 

Here rows is of type IEnumerable<dynamic> . IntelliSense says FirstOrDefault() is expected and has await FirstOrDefault() . Not all LINQ queries appear as expected, but seem to be especially those that highlight some elements.

As soon as I use strong typing instead, this behavior disappears.

This is because .NET cannot know if the type you are getting at runtime expects it or not to let it "resolve" if you need it? But does not enforce it? Or should I, due to some behavior of the dynamic Runtime language, use await here?

I continued to search, but did not find the smallest thing about it on the Internet.

+6
source share
1 answer

async-await compiler function is dependent on Duck Typing . So, all that the GetAwaiter method GetAwaiter (either an instance or an extension method) that returns a type that implements the INotifyCompletion interface and has the following fields:

  • bool IsCompleted { get; }
  • void|TResult GetResult()

can be expected.

You can call whatever you want for the dynamic type at compile time (from docs ):

At compile time, it is assumed that an element that is entered as dynamic supports any operation.

This is why the compiler does not show any warnings / errors at compile time, but at runtime you will get an exception similar to the following:

RuntimeBinderException.

'<> f__AnonymousType0' does not contain a definition for GetAwaiter

If you specify a type, the compiler will explicitly look for the GetAwaiter method. Then, if your strong type does not contain it, you will get a compile-time error.

So, the answer to your question is that because of the special behavior of dynamic .

+8
source

All Articles