c# - 为什么 dynamic 关键字不能用于动态加载的程序集?

标签 c# dynamic-keyword dynamic-assemblies

我正在开发一个 CSharp 表达式求值器,您可以在下面看到它的用途。该组件生成代码并在内存中对其进行编译,然后加载生成的程序集,创建生成类的实例并运行它。结果保存在字典中。

我的问题是所有运行正常,直到最后一行代码失败并出现异常:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException 'object' does not contain a definition for '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);

有什么想法吗?

谢谢。

最佳答案

编辑:我想我明白了。匿名类型是内部类型,因此该类型对 dynamic 绑定(bind)程序不可见。正在验证...

是的,就是这样。请注意确切的错误消息:“object”不包含“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# 编译器作者想到了一切:)

关于c# - 为什么 dynamic 关键字不能用于动态加载的程序集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5067726/

相关文章:

c# - dynamic 关键字是否*仅*用于动态语言?

android - 如何创建 POJO 类以使用动态键名进行改造

c# - 在 C# 中使用动态访问匿名类型的字段 - 可能吗?

c# - 如何使用表达式生成此属性实现而不是发出 IL?

c# - 动态程序集和方法

c# - IBindingList 更改通知

c# - 正确处理 MVVM 父级中子级引发的事件

c# - List.Sort 两次的效率对比 List.Clone & Sort

c# - 在文本框中拖动文件或文件夹? C#

delegates - 如何将表达式树保存为新的可执行磁盘文件的主要入口点?