Почему этот динамический параметр не работает?

Рассмотрим этот код в проекте:

static void Main(string[] args)
{
    DoSomething(new { Name = "Saeed" });
}

public static void DoSomething(dynamic parameters)
{
    Console.WriteLine(parameters.Name);
}

Это работает как шарм. Однако, как только вы отделите эти две функции на два разных проекта, код сломается:

// This code is in a Console Application
static void Main(string[] args)
{
    ExternalClass.DoSomething(new { Name = "Saeed" });
}

// However, this code is in a Class Library; Another project
public class ExternalClass
{

    public static void DoSomething(dynamic parameters)
    {
        Console.WriteLine(parameters.Name);
    }
}

Ошибка во втором случае:

object 'не содержит определения для' Name '(RuntimeBinderException)

Почему я получаю эту ошибку? Какой альтернативный метод? Как передать динамический параметр методу в другой библиотеке и использовать его там простым способом?

Примечание. Я знаком с ExpandoObject, и я не хочу его использовать.

Ответ 1

Ваш код использует анонимный тип. Первоначально предназначенный для использования в выражении запроса выбора Linq, добавленном в С# версии 3. К сожалению, компилятор С# генерирует их с модификатором доступности для членов в анонимном типе, установленном в внутренний. Доступность обеспечивается CLR. Не проблема в Linq, так как итератор будет сгенерирован в той же сборке. Использование их с ключевым словом dynamic не было предусмотрено, оно было добавлено в более поздней версии С# версии 4.

Это означает, что он будет работать нормально, пока код находится в одной и той же сборке. Однако, как только вы передаете объект в код в другой сборке, ограничения, введенные внутренним ударом, и он переходит в kaboom.

Просто объявление небольшого открытого класса является обходным путем. ExpandoObject работает тоже, но добавляет лишние накладные расходы.