2014-10-15 4 views
0

Следующая бросает исключение во время выполнения на последней строке:Неожиданное поведение с динамическим Список

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>» не содержит определения для «First '

Что здесь происходит? Это выглядит вполне законным. Он явно признается как List<ExpandoObject>, а общая коллекция не должна заботиться о значении T .. правильно?

+0

Это ошибка времени компиляции? если это так, попробуйте включить использование пространства имен System.Linq – NMK

+1

ExtensionMethods разрешены (во время компиляции) на статические методы, которые берут исходный код в качестве первого аргумента. Динамический во время выполнения. Если вы вызываете статический метод напрямую и поставляете свой динамический список в качестве первого аргумента, он может работать. – Silvermind

ответ

4

Метод First() является extention method, расположенный в System.Linq.Enumerable, а не System.Collections.Generic.List<T>. Это означает, что объект dyanmic, который просматривает членов во время выполнения, не может решить, что означает .First(), потому что List<T> делает, как сказано, не содержит этого метода. Большая проблема заключается в том, что он ищет члена и не проверяет методы расширения, когда он идет, чтобы решить проблему.

Синтаксически, вы можете сказать List<T>.First(), потому что это синтаксический сахар. Вы также можете обратиться к полному методу, и вам нужно будет заставить этот код работать, потому что объекты dynamic не проверяют методы расширения.

Enumerable.First(dyanmicCollection); 

Во время компиляции, это то, что методы расширения эффективно расширяться в любом случае, так что вы в основном минуя сахар,

+0

Вы попробовали мой пример? Думаю, тебе не хватает моего вопроса. У меня нет проблемы с First() вообще. – aw04

+0

Приношу свои извинения! Я вижу ответ сейчас, обновляя соответственно – David

+0

Да, это имеет смысл. Спасибо за объяснение. – aw04

1

Вам действительно нужно dynamicCollection быть dynamic? Если нет, то вы можете использовать конкретный тип для самого списка:

var dynamicCollection = new List<ExpandoObject>(); 
... 
dynamic firstItem = dynamicCollection.First(); 
Console.WriteLine(firstItem.Name); 

, а затем dynamicCollection.First() будет разрешен как вызов метода расширения, как вы ожидаете. Тип возврата этого метода: ExpandoObject, поэтому вы также должны указать его dynamic для доступа к Name.

+0

Да, да. Примером является простое представление проблемы. Хороший момент, может быть, может помочь кому-то другому. – aw04

Смежные вопросы