Reputation: 11187
The following throws a runtime exception on the last line:
dynamic dynamicCollection = new List<ExpandoObject>();
dynamic itemOne = new ExpandoObject();
itemOne.Name = "itemOne";
dynamicCollection.Add(itemOne);
dynamic itemTwo = new ExpandoObject();
itemTwo.Name = "itemTwo";
dynamicCollection.Add(itemTwo);
var firstItem = dynamicCollection.First();
'System.Collections.Generic.List<System.Dynamic.ExpandoObject>' does not contain a definition for 'First'
What's happening here? This looks completely legal. It's clearly being recognized as a List<ExpandoObject>
, and a generic collection should not care about the value of T
.. right?
Upvotes: 0
Views: 70
Reputation: 4394
Do you really need dynamicCollection
to be dynamic
? If not, you can use concrete type for the list itself:
var dynamicCollection = new List<ExpandoObject>();
...
dynamic firstItem = dynamicCollection.First();
Console.WriteLine(firstItem.Name);
and then dynamicCollection.First()
will be resolved as an extension method call as you expect.
Return type of this method is ExpandoObject
, so you also should cast it to dynamic
to access Name
property.
Upvotes: 1
Reputation: 10708
The First()
method is an extention method located in System.Linq.Enumerable
rather than System.Collections.Generic.List<T>
. This means that a dyanmic
object, which looks up members at runtime, cannot resolve what .First()
means because List<T>
does, as said, not contain that method. The big issue here is that it's looking for a member, and doesn't check for Extension Methods when it goes to resolve.
Syntactically, you can say List<T>.First()
because it's syntactic sugar. You can also refer to the full method, and you'll have to get this code to work, because dynamic
objects don't check for extension methods.
Enumerable.First(dyanmicCollection);
At compile time, this is what extension methods effectively expand to anyway, so you're basically bypassing the sugar,
Upvotes: 4