c# - 评估来自字符串的嵌套属性调用

标签 c# python reflection roslyn

我目前正在阅读“500 行或更少”bookchapter用于从 Ned Batchelder 创建模板引擎。

他们的示例是使用 Python。在他们的模板引擎中,他们将代码构建为字符串,然后调用 exec ( docs ) 将该字符串评估为 Python 代码。

def get_globals(self):
    """Execute the code, and return a dict of globals it defines."""
    # A check that the caller really finished all the blocks they started.
    assert self.indent_level == 0
    # Get the Python source as a single string.
    python_source = str(self)
    # Execute the source, defining globals, and return them.
    global_namespace = {}
    exec(python_source, global_namespace)
    return global_namespace

这非常方便,因为它们可以轻松地计算模板中的表达式,例如 {{object.property.property}}

以 C# 作为我的主要编程语言,我想知道如何实现这一点(在构建书中的模板引擎的背景下)?

研究与思考

首先,我不相信 C# 中有等价的 exec

我能想到的一种方法是递归地使用反射来获取对象的属性列表(处理空引用的检查),但从性能的角度来看我不喜欢这样做。

另一种方法是使用 Roslyn 的 ScriptEngine 类(我没有使用过,所以如果我错了请纠正我)。但我担心这不会很好,因为这应该是一个库,并且它无法与旧版本的 C# 和 .NET 一起使用。 Example

最佳答案

Q: First I don't believe there is an exec equivalent in C#.

对于编译C#代码,CS-Script可以使用库以多种方式实现此目的。

例如:

dynamic script = CSScript.Evaluator
                         .LoadCode(@"using System;
                                     using Your.Custom.Relevant.Namespace;
                                     public class Executer
                                     {
                                         public object Execute()
                                         {
                                             return SomeStaticClass.array[123];
                                         }
                                     }");
int result = script.Execute();

//shorter way
int a = (int)CSScript.Evaluator.Evaluate("some.namespace.SomeStaticClass.array[123]");

在此处了解更多信息:http://www.csscript.net/

CS-Script 不是用于模板化的。
除非您在编译字符串之前通过操作字符串来创建它。

But how can I pass some Context for the template engine

您可以将上下文传递到函数中,如下所示:

dynamic script = CSScript.Evaluator
                     .LoadCode(@"
                                using System;
                                using Namespace.Of.The.Context;
                                public class Executer {
                                    public string Execute(Context ctx) {
                                        return ctx.Person.Firstname + ctx.Person.Lastname;
                                    }
                                }");
int result = script.Execute(new Context(new Person("Rick", "Roll")));

Q: Can I call CSScript from a normal C# application lets say a Web App?

A: Yes.

S-Script currently targets Microsoft implementation of CLR (.NET 2.0/3.0/3.5/4.0/4.5) with full support on Mono.

基本上,如果它运行 C#,它可以根据执行该库的 .net 框架进行编译,因此,如果您的项目在 .net4.5 上运行,则该 .net 版本的任何功能都可用,包括任何您的项目中也有外部引用。

关于c# - 评估来自字符串的嵌套属性调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34560670/

相关文章:

python - 沿动态指定的轴切片 numpy 数组

python - 如何在 Python PyAutoGUI 中更改键盘

c# - 订阅已加载程序集的事件

java - Java中是否可以通过反射在新进程中调用main方法

python - 如何检查变量是否是类?

c# - 如何使用 C# 锁定文件?

c# - 为什么在传递命名方法时不能推断出这些类型参数?

python - Python 中的对象类型转换(设计建议)

c# - Anders Hejlsberg 的 C# 4.0 REPL

c# - 我的 asp.net Web 应用程序中使用 C# 的 mysql 出现超时过期错误?