【问题标题】:Why doesn't dynamic keyword work with dynamically loaded assemblies?为什么动态关键字不适用于动态加载的程序集?
【发布时间】:2011-02-21 15:23:30
【问题描述】:

我正在开发一个 CSharp 表达式评估器,如下所示。该组件生成代码并在内存中编译它,然后加载生成的程序集,创建生成的类的实例并运行它。结果保存在字典中。

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

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException“对象”不包含“名字”的定义。

然而,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);

有什么想法吗?

谢谢。

【问题讨论】:

    标签: c# dynamic-keyword dynamic-assemblies


    【解决方案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# 编译器的作者什么都想:)

    【讨论】:

    • 对不起,乔恩,我的问题描述有误。执行语句后:dynamic professional = eval["professional"]; VS 正确显示了专业变量内容。但是,程序在下一行失败。
    • c# 编译器团队的人永远不会停止给我带来惊喜。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    • 2018-10-01
    • 2016-10-24
    • 1970-01-01
    相关资源
    最近更新 更多