Dynamic 静态使用.NET 4.0动态对象?

Dynamic 静态使用.NET 4.0动态对象?,dynamic,c#-4.0,dynamic-language-runtime,Dynamic,C# 4.0,Dynamic Language Runtime,我在这里问了另一个与此相关的问题: 我已经厌倦了.NET中的XML配置文件,希望用一种更合理的格式来替换它们。因此,我正在为C应用程序编写一个配置文件解析器,它将采用自定义配置文件格式,对其进行解析,并创建一个Python源字符串,然后我可以在C中执行该字符串并将其用作静态对象。是的,没错,我最终想要的是一个静态对象,而不是静态类型的动态对象 下面是我的配置文件的示例: // my custom config file format GlobalName: ExampleApp Propert

我在这里问了另一个与此相关的问题:

我已经厌倦了.NET中的XML配置文件,希望用一种更合理的格式来替换它们。因此,我正在为C应用程序编写一个配置文件解析器,它将采用自定义配置文件格式,对其进行解析,并创建一个Python源字符串,然后我可以在C中执行该字符串并将其用作静态对象。是的,没错,我最终想要的是一个静态对象,而不是静态类型的动态对象

下面是我的配置文件的示例:

// my custom config file format
GlobalName: ExampleApp

Properties
{
    ExternalServiceTimeout: "120"
}

Python 
{
    // this allows for straight python code to be added to handle custom config
    def MyCustomPython:
     return "cool"
}
我使用创建了一个Lexer/Parser,它将这种格式转换为Python脚本。因此,假设我已经准备好了,可以使用上面的.config并在其上运行我的Lexer/Parser,以获得一个Python脚本。这还有一个额外的好处,就是为我的配置提供了一个验证工具。通过在C中运行生成的脚本

// simplified example of getting the dynamic python object in C#
// (not how I really do it)
ScriptRuntime py = Python.CreateRuntime(); 
dynamic conf = py.UseFile("conftest.py");
dynamic t = conf.GetConfTest("test");
我可以获得具有我的配置设置的动态对象。现在,我可以通过调用该对象上的动态方法在C中获取配置文件设置:

//C# calling a method on the dynamic python object
var timeout = t.GetProperty("ExternalServiceTimeout");
//the config also allows for straight Python scripting (via the Python block)
var special = t.MyCustonPython();
当然,我这里没有类型安全性,也没有intellisense支持。我有一个配置文件的动态表示,但我想要一个静态的。我知道Python对象的类型,它实际上是在C类的实例中更新的。但由于它发生在python中,所以它的类型不是C类型,而是动态的。我想做的是将对象转换回C类型,我知道该对象是:

有没有办法弄清楚如何将对象强制转换为静态类型?我很怀疑是否有。。。如此怀疑以至于我采取了另一种我不完全确定的方法。我想知道是否有人有更好的方法

现在我的策略是:既然我知道python对象的类型,我就创建一个C包装器类:

public class ConfigSettings : IConfigSettings
在ctor中接收动态对象的:

    public ConfigSettings(dynamic settings)
    {
        this.DynamicProxy = settings;
    }

    public dynamic DynamicProxy
    {
        get;
        private set;
    }
现在我有一个Python动态对象的引用,我知道它的类型。因此,我可以在我知道的Python方法周围放置包装:

// wrapper access to the underlying dynamic object
// this makes my dynamic object appear 'static' 
public string GetSetting(string key)
{
    return this.DynamicProxy.GetProperty(key).ToString();
}
现在动态对象是通过这个静态代理访问的,因此显然可以通过接口等在静态C世界中传递:

// dependency inject the dynamic object around
IBusinessLogic logic = new BusinessLogic(IConfigSettings config);
此解决方案具有我们所了解和喜爱的所有静态键入功能的优点,同时也为我提供了“退出”到动态的选项:

// the DynamicProxy property give direct access to the dynamic object
var result = config.DynamicProxy.MyCustomPython();

但是,老兄,这似乎是一种相当复杂的方式来获取一个静态类型的对象!因为整个动态/静态交互世界对我来说都是新的,我真的在质疑我的解决方案是否是最优的,或者我是否遗漏了一些东西,例如,如何将动态对象转换为已知的静态类型,如何弥合这两个宇宙之间的鸿沟。

如果IConfigSettings staticTypeConfig=t作为IConfigSettings不起作用,那么实际上您没有一个正在实现的对象i配置设置。假设使用Python声明类,则应确保在基类列表中包含接口,例如:

class C(IConfigSettings):
   def SomeIConfigSettingsMember(self): pass

如果这不起作用,那么发布Python代码可能会有所帮助。

请参阅此处的拆分问题,它提供了一种实现此功能的方法。

开源框架允许您声明静态c接口和包装任何动态对象。

这似乎比XML更明智。只是说…我想你把引擎和.config文件本身搞混了。。。.config文件本身比IMHO.hmm更理智。我不明白我做错了什么。我只是试着用python更新并返回一个System.Uri对象,我可以用C将它转换成System.Uri。但我不能让它与我自己的类型一起工作。我把这个问题分成了另一个更具体的问题,因为我无法让它工作:
class C(IConfigSettings):
   def SomeIConfigSettingsMember(self): pass