我在这里问了另一个相关的问题: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();
但是,男人,这似乎相当转到一个静态类型的对象首先得到一个对象!由于整个动态/静态交互的世界对我来说是新的,我真的质疑我的解决方案是否最优,或者如果我错过了某些东西(即将某个动态对象转换为已知静态类型的方式)这两个宇宙之间的鸿沟。
这似乎没有比XML更健全。只是说... – 2010-05-06 19:14:52
我认为你得到的引擎和.config文件本身困惑... .config文件本身是相当多一点理智恕我直言。 – 2010-05-06 19:25:43