ここでこれに関連する別の質問をしました:動的から静的な問題へのキャスト
私は .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
dynamic
ctor 内のオブジェクトを取り込みます。
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();
しかし、これは、そもそも静的型であるオブジェクトに到達するためのかなり複雑な方法のようです! 動的/静的相互作用の世界全体が私にとって初めてなので、私の解決策が最適かどうか、または何かが欠けているかどうか (つまり、その動的オブジェクトを既知の静的型にキャストする方法) を本当に疑問に思っています。この二つの宇宙の間の裂け目。