2010-05-06 75 views
1

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

但是,男人,這似乎相當轉到一個靜態類型的對象首先得到一個對象!由於整個動態/靜態交互的世界對我來說是新的,我真的質疑我的解決方案是否最優,或者如果我錯過了某些東西(即將某個動態對象轉換爲已知靜態類型的方式)這兩個宇宙之間的鴻溝。

+1

這似乎沒有比XML更健全。只是說... – 2010-05-06 19:14:52

+0

我認爲你得到的引擎和.config文件本身困惑... .config文件本身是相當多一點理智恕我直言。 – 2010-05-06 19:25:43

回答

0

如果「IConfigSettings staticTypeConfig = t as IConfigSettings」不起作用,那麼實際上並沒有實現IConfigSettings的對象。假設你宣佈在Python的類,你應該確保在包括基類列表的接口,例如:

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

如果不工作,那麼,如果你發佈Python代碼,因爲它可能會幫助好。

+0

嗯。我不明白我在做什麼錯誤,我只是試着用python新建一個System.Uri對象,我可以把它用C#轉換成System.Uri,但是我不能讓它與我自己的類型一起工作 – 2010-05-06 22:52:40

+0

我把它分解成另一個更具體的問題,因爲我沒有得到這個工作:http://stackoverflow.com/questions/2785252/c-4-0-casting-dynamic-與靜態 – 2010-05-06 23:42:25