Метод расширения и динамический объект - PullRequest
91 голосов
/ 15 марта 2011

Я собираюсь обобщить мою проблему в следующем фрагменте кода.

List<int> list = new List<int>() { 5, 56, 2, 4, 63, 2 };
Console.WriteLine(list.First());

Над кодом работает нормально.

Теперь я попробовал следующее

dynamic dList = list;
 Console.WriteLine(dList.First());

но я получаю RuntimeBinderException. Почему это так?

Ответы [ 3 ]

129 голосов
/ 15 марта 2011

Чтобы расширить ответ Джона, причина, по которой это не работает, заключается в том, что в обычных, не динамических методах расширения кода работает полный поиск всех классов, известных компилятору, для статического класса, который имеет метод расширения.это соответствует.Поиск идет в порядке, основанном на вложенности пространства имен и доступных директивах using в каждом пространстве имен.

Это означает, что для правильного разрешения вызова метода динамического расширения каким-то образом DLR должен знать во время выполнения , что все вложения пространства имен и директивы using были вваш исходный код .У нас нет удобного механизма для кодирования всей этой информации в сайт вызова.Мы рассмотрели вопрос об изобретении такого механизма, но решили, что это слишком дорого, и привели к слишком большому риску графика, чтобы стоить того.

122 голосов
/ 15 марта 2011

Чтобы расширить ответ Stecya ... методы расширения не поддерживаются динамическим вводом в форме методов расширения , то есть вызываются так, как если бы они были методами экземпляра. Тем не менее, это будет работать:

dynamic dList = list;
Console.WriteLine(Enumerable.First(dList));

Конечно, это может или не может быть полезным. Если бы вы могли дать больше информации о том, почему и как вы пытаетесь использовать динамическую типизацию, мы могли бы помочь вам больше.

18 голосов
/ 15 марта 2011

Потому что First() не является методом List.Это определено в Расширении Linq до IEnumerable<>

...