我在這裏問了另一個相關的問題: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