为什么动态关键字不适用于动态加载的程序集?
我正在开发一个 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);
有什么想法吗?
谢谢。
I'm working on a CSharp expression evaluator which can be used as you can see below. This component generates code and compiles it in memory and after that, it loads the generated assembly, creates an instance of the generated class and run it. Results are saved in a dictionary.
My problem is that all run ok until the last line of code where it fails with the exception:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException 'object' does not contain a definition for 'FirstName'.
However, Visual Studio is able to show me the professional variable content:
Professional = { FirstName = Juan Pablo,
LastName = Ibañez,
Certifications = <>f__AnonymousType0`3[System.String,System.String,System.String][],
SayHi = System.Action }
And this is the code:
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);
Any ideas?
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编辑:我想我已经明白了。匿名类型是内部类型,因此该类型对于
动态
绑定器不可见。现在正在验证...是的,就是这样。请注意确切的错误消息:
'object' 不包含 'FirstName'" 的定义。
它使用
object
因为这是您实际上可以使用的唯一类型 em> 从您自己的程序集中引用该对象。这与动态加载的程序集无关 - 这只是它位于不同程序集中的问题:您可以绕过。使用
[InternalsVisibleTo]
属性,如果您可以使您的“发布”程序集应用该属性,请参阅以下示例:如果您注释掉该属性,则 Test.exe 将根据您的问题进行中断。 ,它工作得很好。C# 编译器作者考虑了一切:)
EDIT: I think I've got it. Anonymous types are internal, so the type isn't visible to the
dynamic
binder. Verifying now...Yup, that's it. Note the exact error message:
'object' does not contain a definition for 'FirstName'".
It's using
object
because that's the only type you could actually refer to the object as from within your own assembly. This has nothing to do with the assembly being loaded dynamically - it's simply a matter of it being in a different assembly.EDIT: You can get round this using the
[InternalsVisibleTo]
attribute, if you can make your "publishing" assembly apply that. Here's an example:If you comment out the attribute, Test.exe breaks as per your question. With the attribute, it works fine. The C# compiler authors think of everything :)