.NET 4.0静态使用动态对象? [英] .NET 4.0 Dynamic object used statically?
问题描述
我已经厌倦了.NET中的XML配置文件,并希望用更合理的格式替换它们。因此,我正在为C#应用程序编写一个配置文件解析器,该配置文件解析器将采用自定义配置文件格式,解析它,并创建一个Python源字符串,然后我可以在C#中执行,并用作 static
对象(是的,是的 - 我想要一个 static
(不是静态类型dyanamic)对象到最后)。
以下是我的配置文件的示例:
//我的自定义配置文件格式
GlobalName:ExampleApp
属性
{
ExternalServiceTimeout:120
}
Python
{
//这允许添加直接python代码来处理自定义配置
def MyCustomPython:
返回酷
}
使用 ANTLR 我创建了一个Lexer / Parser,将此格式转换为Python脚本。所以假设我有这一切,可以把上面的.config,并运行我的Lexer / Parser来获取一个Python脚本(这有额外的好处,给我一个验证工具为我的配置)。通过在C#中运行结果脚本
//在C#中获取动态python对象的简化示例
//不是我真的这样做)
ScriptRuntime py = Python.CreateRuntime();
dynamic conf = py.UseFile(conftest.py);
dynamic t = conf.GetConfTest(test);
我可以获得一个动态
我的配置设置。我现在可以通过调用该对象的动态方法来获取C#中的配置文件设置:
// C#调用一个方法动态python对象
var timeout = t.GetProperty(ExternalServiceTimeout);
//该配置还允许直接的Python脚本(通过Python块)
var special = t.MyCustonPython();
当然,这里没有类型安全,没有智能支持。我有一个动态
表示我的配置文件,但我想要一个静态的。我知道我的Python对象的类型是什么 - 它实际上是一个C#类的例子。但是由于它在python中发生,所以它的类型不是C#类型,而是动态
。那么我想要要做的就是将对象转回C#类型,我知道对象是:
//不起作用 - 不能将动态转换为静态类型(nulls)
IConfigSettings staticTypeConfig = t作为IConfigSettings
有没有办法找出如何将对象转换为静态类型?我很怀疑有这样的疑问,我采取了另一种我不完全确定的方法。 我想知道有没有更好的方法...
所以这里是我目前的策略:因为我知道python对象的类型,我正在创建一个C#包装类:
public class ConfigSettings:IConfigSettings
/ pre>
在ctor中
动态
对象:public ConfigSettings(动态设置)
{
this.DynamicProxy = settings;
}
public dynamic DynamicProxy
{
get;
私人集;
}
现在我有一个Python动态对象的引用,我知道它的类型。所以我可以把包装器围绕着我所知道的Python方法:
//对底层动态对象的包装访问
//这使得我的动态对象出现'static'
public string GetSetting(string key)
{
return this.DynamicProxy.GetProperty(key).ToString();
}
现在通过静态代理访问动态对象,因此显然可以传递在静态C#世界通过接口等等:
//依赖注入动态对象
IBusinessLogic逻辑=新的BusinessLogic(IConfigSettings config);
此解决方案具有我们所熟悉和喜爱的所有静态打字内容的优点,同时给予我的bailing out动态选项:
// DynamicProxy属性可以直接访问动态对象
var result = config.DynamicProxy.MyCustomPython();
但是,这个似乎相当的复杂的方式来获取一个静态的对象首先输入!由于整个动态/静态互动世界对我来说是新的,所以我真的怀疑我的解决方案是否是最佳的,或者如果我缺少某些东西(即某种方式将该动态对象转换为一个已知的静态类型)关于如何桥接这两个宇宙之间的鸿沟。
解决方案看到分裂问题在这里 C#4.0:将动态转换为静态,提供了一种使其工作的方式。 / p>
I've asked another related question to this here: casting dynamic to static problem
I've gotten quite sick of XML configuration files in .NET and want to replace them with a format that is more sane. Therefore, I'm writing a config file parser for C# applications that will take a custom config file format, parse it, and create a Python source string that I can then execute in C# and use as a
static
object (yes that's right--I want astatic
(not the static type dyanamic) object in the end).Here's an example of what my config file looks like:
// 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" }
Using ANTLR I've created a Lexer/Parser that will convert this format to a Python script. So assume I have that all right and can take the .config above and run my Lexer/Parser on it to get a Python script out the back (this has the added benefit of giving me a validation tool for my config). By running the resultant script in 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");
I can get a
dynamic
object that has my configuration settings. I can now get my config file settings in C# by invoking a dynamic method on that object://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();
of course, I have no type safety here and no intellisense support. I have a
dynamic
representation of my config file, but I want a static one. I know what my Python object's type is--it is actually newing up in instance of a C# class. But since it's happening in python, it's type is not the C# type, butdynamic
instead. What I want to do is then cast the object back to the C# type that I know the object is:// doesn't work--can't cast a dynamic to a static type (nulls out) IConfigSettings staticTypeConfig = t as IConfigSettings
Is there any way to figure out how to cast the object to the static type? I'm rather doubtful that there is... so doubtful that I took another approach of which I'm not entirely sure about. I'm wondering if someone has a better way...
So here's my current tactic: since I know the type of the python object, I am creating a C# wrapper class:
public class ConfigSettings : IConfigSettings
that takes in a
dynamic
object in the ctor:public ConfigSettings(dynamic settings) { this.DynamicProxy = settings; } public dynamic DynamicProxy { get; private set; }
Now I have a reference to the Python dynamic object of which I know the type. So I can then just put wrappers around the Python methods that I know are there:
// 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(); }
Now the dynamic object is accessed through this static proxy and thus can obviously be passed around in the static C# world via interface, etc:
// dependency inject the dynamic object around IBusinessLogic logic = new BusinessLogic(IConfigSettings config);
This solution has the benefits of all the static typing stuff we know and love while at the same time giving me the option of 'bailing out' to dynamic too:
// the DynamicProxy property give direct access to the dynamic object var result = config.DynamicProxy.MyCustomPython();
but, man, this seems rather convoluted way of getting to an object that is a static type in the first place! Since the whole dynamic/static interaction world is new to me, I'm really questioning if my solution is optimal or if I'm missing something (i.e. some way of casting that dynamic object to a known static type) about how to bridge the chasm between these two universes.
解决方案see the split off question here C# 4.0: casting dynamic to static that provides a way of making this work.
这篇关于.NET 4.0静态使用动态对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!