2010-05-06 78 views
1

我在这里问了另一个相关的问题:casting dynamic to static problem.NET 4.0动态对象静态使用?

我对.NET中的XML配置文件感到厌倦,想用一种更为理智的格式替换它们。因此,我正在为C#应用程序编写一个配置文件解析器,它将采用自定义配置文件格式,解析它,然后创建一个Python源字符串,然后我可以在C#中执行并用作static对象(是的 - 我最终需要一个static(不是静态类型的dyanamic)对象。

下面是一个什么我的配置文件看起来像例如:使用ANTLR我创建了一个词法分析器/分析器,将这种格式转换为Python脚本

// 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" 
} 

。所以假设我没有问题,并且可以使用上面的.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"); 

我可以得到有我的配置设置dynamic对象。我现在可以通过对象调用动态方法得到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支持。我有一个dynamic表示我的配置文件,但我想要一个静态的。我知道我的Python对象的类型是什么 - 它实际上是新的C#类的实例。但是,因为它发生在python中,所以它的类型不是C#类型,而是dynamic。我做的就是再投对象返回到C#类型,我知道对象是

// doesn't work--can't cast a dynamic to a static type (nulls out) 
IConfigSettings staticTypeConfig = t as IConfigSettings 

有什么办法弄清楚如何将对象转换为静态类型?我非常怀疑,我怀疑我采取了另一种我不完全确定的方法。 我想知道,如果有人有一个更好的办法...

因此,这里是我目前的策略:因为我知道蟒蛇对象的类型,我创建一个C#包装类:

public class ConfigSettings : IConfigSettings 

它接受一个dynamic对象在构造函数:

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(); 

但是,男人,这似乎相当转到一个静态类型的对象首先得到一个对象!由于整个动态/静态交互的世界对我来说是新的,我真的质疑我的解决方案是否最优,或者如果我错过了某些东西(即将某个动态对象转换为已知静态类型的方式)这两个宇宙之间的鸿沟。

+1

这似乎没有比XML更健全。只是说... – 2010-05-06 19:14:52

+0

我认为你得到的引擎和.config文件本身困惑... .config文件本身是相当多一点理智恕我直言。 – 2010-05-06 19:25:43

回答

0

如果“IConfigSettings staticTypeConfig = t as IConfigSettings”不起作用,那么实际上并没有实现IConfigSettings的对象。假设你宣布在Python的类,你应该确保在包括基类列表的接口,例如:

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

如果不工作,那么,如果你发布Python代码,因为它可能会帮助好。

+0

嗯。我不明白我在做什么错误,我只是试着用python新建一个System.Uri对象,我可以把它用C#转换成System.Uri,但是我不能让它与我自己的类型一起工作 – 2010-05-06 22:52:40

+0

我把它分解成另一个更具体的问题,因为我没有得到这个工作:http://stackoverflow.com/questions/2785252/c-4-0-casting-dynamic-与静态 – 2010-05-06 23:42:25