.NET 4.0静态使用动态对象? [英] .NET 4.0 Dynamic object used statically?

查看:136
本文介绍了.NET 4.0静态使用动态对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里提出了另一个相关问题:将动态类型转换为静态类型问题

I've asked another related question to this here: casting dynamic to static problem

我对.NET中的XML配置文件感到相当不满,并希望将它们替换为更加平稳的格式。因此,我编写一个配置文件解析器为C#应用程序,将采取自定义配置文件格式,解析它,并创建一个Python源字符串,然后我可以在C#中执行,并使用作为一个 static object(是的,是的 - 我想要一个 static (不是静态类型dyanamic)对象)。

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 a static (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"
}

使用 ANTLR < a>我创建了一个Lexer / Parser,它会将此格式转换为Python脚本。所以假设我没有错误,可以采取上面的.config并运行我的Lexer / Parser在它的后面得到一个Python脚本(这有额外的好处给我一个验证工具为我的配置)。通过在C#中运行结果脚本

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

当然,我没有类型安全,没有intellisense支持。我有一个动态表示我的配置文件,但我想要一个静态。我知道我的Python对象的类型是什么 - 它实际上是在C#类的实例。但是由于它发生在python中,它的类型不是C#类型,而是 dynamic 希望做的是将对象强制转换回C#类型,我知道对象

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, but dynamic 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...

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

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

在ctor中接受动态对象:

that takes in a dynamic object in the ctor:

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

    public dynamic DynamicProxy
    {
        get;
        private set;
    }



现在我有一个Python动态对象的引用,中。所以我可以把包装器围绕我知道的Python方法:

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

现在动态对象通过这个静态代理访问,通过接口等在静态C#世界中:

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

这个解决方案有所有我们知道和喜欢的静态类型的好处,我也可以选择动态的bailing out:

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.

推荐答案

请参阅这里的分割问题 http://stackoverflow.com/questions/2785252/c-4-0-casting-dynamic -to-static ,提供了一种工作方式。

see the split off question here http://stackoverflow.com/questions/2785252/c-4-0-casting-dynamic-to-static that provides a way of making this work.

这篇关于.NET 4.0静态使用动态对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆