Как применить метод расширения для объекта, имеющего тип ExpandoObject?

Вот мой код:

public static class DynamicExtensions

    public static void Add(this ExpandoObject obj, string path){
        dynamic _obj = obj;
        if (_obj == null) throw new ArgumentNullException("obj");
        _obj.path = path;
    }
}

Но у меня ошибка "System.Dynamic.ExpandoObject" не содержит определения для "Добавить", когда я вызываю его следующим образом:

dynamic obj = new ExpandoObject();
obj.Add("p1");

Как это исправить?

Спасибо заранее!

Ответ 1

Проблема заключается в использовании dynamic с методами расширения - они просто не идут вместе. Это будет хорошо:

ExpandoObject obj = new ExpandoObject();
obj.Add("p1");

... но только с dynamic, поддержка метода расширения не поддерживается.

Из раздела 7.6.5.2 спецификации С# 5:

В вызове метода (п. 7.5.5.1) одной из форм

expr . identifier ( )
expr . identifier ( args )
expr . identifier < typeargs > ( )
expr . identifier < typeargs > ( args )

если нормальная обработка вызова не находит применимых методов, делается попытка обработать конструкцию как вызов метода расширения. Если expr или любой из аргументов имеют динамический тип времени компиляции, методы расширения не будут применяться.

В то время как компилятор мог помнить директивы using, которые должны были бы проверять для применения методов расширения, это просто не возможно, возможно, по соображениям производительности, или, возможно, потому, что было просто ощутимо много работы относительно мало пользы.

Ответ 2

Динамический явно исключает методы расширения. Это связано с тем, что метод разрешен во время выполнения, а не во время компиляции. Чтобы правильно разрешить вызов метода, DLR будет нужна информация о вызове, который включает в себя действия, которые используют директивы; нет механизма для этого. См. Этот ответ Эрика Липперта для более подробной информации: fooobar.com/info/37954/...

Вы можете, конечно, вызвать метод, используя синтаксис вызова статического метода:

DynamicExtensions.Add(obj, "p1");