1

ここでこれに関連する別の質問をしました:動的から静的な問題へのキャスト

私は .NET の XML 構成ファイルにかなりうんざりしており、より健全な形式に置き換えたいと考えています。そのため、カスタムの構成ファイル形式を取得して解析し、C# で実行してオブジェクトとして使用できる Python ソース文字列を作成する C# アプリケーション用の構成ファイル パーサーを作成していstaticます (はい、そうです。static最後に(静的タイプの動的ではない)オブジェクトが必要です)。

私の構成ファイルがどのように見えるかの例を次に示します。

// 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を使用して、この形式を Python スクリプトに変換する Lexer/Parser を作成しました。それで、私はそれで問題ないと仮定し、上記の .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

オブジェクトを静的型にキャストする方法を理解する方法はありますか? 私はかなり疑わしいです... あまりにも疑わしいので、私は完全に確信が持てない別のアプローチを取りました. 誰かもっといい方法ないかな…

ここに私の現在の戦術があります: 私は Python オブジェクトの型を知っているので、C# ラッパー クラスを作成しています:

public class ConfigSettings : IConfigSettings

dynamicctor 内のオブジェクトを取り込みます。

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

しかし、これは、そもそも静的型であるオブジェクトに到達するためのかなり複雑な方法のようです! 動的/静的相互作用の世界全体が私にとって初めてなので、私の解決策が最適かどうか、または何かが欠けているかどうか (つまり、その動的オブジェクトを既知の静的型にキャストする方法) を本当に疑問に思っています。この二つの宇宙の間の裂け目。

4

3 に答える 3

0

「IConfigSettingsstaticTypeConfig=t as IConfigSettings」が機能していない場合は、IConfigSettingsを実装しているオブジェクトは実際にはありません。Pythonでクラスを宣言していると仮定すると、基本クラスリストにインターフェイスを含める必要があります。次に例を示します。

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

それがうまくいかない場合は、Pythonコードも投稿すると役立つ場合があります。

于 2010-05-06T19:39:57.907 に答える
0

こちらの分割の質問を参照してくださいC# 4.0: cast dynamic to staticこれは、この作業を行う方法を提供します。

于 2010-09-17T00:28:37.610 に答える
0

オープン ソース フレームワークのimpromptu インターフェイスを使用すると、静的な c# インターフェイスを宣言し、任意の動的オブジェクトをラップできます。

于 2011-03-14T05:03:46.287 に答える