Почему динамическое ключевое слово не работает с динамически загружаемыми сборками?

Я работаю над оценщиком выражений CSharp, который можно использовать, как вы можете видеть ниже. Этот компонент генерирует код и компилирует его в памяти, а затем загружает сгенерированную сборку, создает экземпляр сгенерированного класса и запускает его. Результаты сохраняются в словаре.

Моя проблема в том, что все работает нормально до последней строки кода, где происходит сбой, за исключением:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException "объект" не содержит определения для "FirstName".

Тем не менее, Visual Studio может показать мне профессиональный переменный контент:

Professional = { FirstName = Juan Pablo, 
                LastName = Ibañez, 
                Certifications = <>f__AnonymousType0`3[System.String,System.String,System.String][], 
                SayHi = System.Action }

И это код:

    static void Main(string[] args)
    {
        const string data = @"results[""professional""] = 
        new
        {
            FirstName = ""Juan Pablo"",
            LastName = ""Ibañez"",
            Certifications = new[]
            {
                new { Provider=""MSFT"", ExamCode = ""70-536"", Title = ""TS: Microsoft .NET Framework – Application Development Foundation"" },
                new { Provider=""MSFT"", ExamCode = ""70-505"", Title = ""TS: Microsoft .NET Framework – Application Development Foundation"" },
                new { Provider=""MSFT"", ExamCode = ""70-563"", Title = ""TS: Microsoft .NET Framework – Application Development Foundation"" }
            },

            SayHi = new System.Action(()=> System.Console.WriteLine(""Hi""))
        };";

        var eval = CSharpEvaluator.Evaluate(data); // return a disctionary<string, object>
        dynamic professional = eval["professional"];
        Console.WriteLine("First Name: {0}", professional.FirstName);

Есть идеи?

Спасибо.

1 ответ

РЕДАКТИРОВАТЬ: Я думаю, что у меня есть. Анонимные типы являются внутренними, поэтому тип не виден dynamic связующее. Проверка сейчас...

Да, это так. Обратите внимание на точное сообщение об ошибке: 'object' does not contain a definition for 'FirstName'".

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

РЕДАКТИРОВАТЬ: Вы можете обойти это с помощью [InternalsVisibleTo] атрибут, если вы можете заставить вашу "публикуемую" сборку применить это. Вот пример:

// In Library.dll
using System.Runtime.CompilerServices;
[assembly:InternalsVisibleTo("Test")]

public class Library
{
    public static object Foo()
    {
        return new { ID = 1 };
    }
}

// In Test.exe
using System;

class Test
{
    static void Main()
    {
        dynamic d = Library.Foo();
        Console.WriteLine(d.ID);
    }
}

Если вы закомментируете атрибут, Test.exe прекратит работу в соответствии с вашим вопросом. С атрибутом все работает нормально. Авторы компилятора C# думают обо всем:)

Другие вопросы по тегам