2010-02-11 75 views
2

我使用FileHelpers解析CSV文件,其結構是未知的使用下面的代碼:如何訪問在運行時定義類型的對象?

  string cd = string.Format(@"[DelimitedRecord(""{0}"")] 
             public sealed class ImportClass {{ 
              [FieldQuoted('{1}')] 
              public string[] Fields; 
             }}", _delimiter, _quote); 
      Type t = DelimitedClassBuilder.ClassFromString(cd); 

      var engine = new FileHelperAsyncEngine(t); 

      engine.BeginReadFile(filename); 
      object record; 
      while ((record = engine.ReadNext()) != null) { 

      } 

      engine.Close(); 

這似乎工作得很好。當我用調試器遍歷它時,record是一個ImportClass類型的對象,而Fields字段正確地填充了來自該文件的數據。

我遇到的問題是我如何實際提取數據?我無法將記錄轉換爲ImportClass,因爲該類型在編譯時未知。我真的需要使用反射還是有更簡單的方法來做到這一點?

回答

0

這可能是一個乾淨的方式,由您使用的庫提供。不過,這裏是一個普遍的答案使用反射:

Type t = ... // You already have this 
PropertyInfo fieldsProperty = t.GetProperty("Fields", 
    BindingFlags.Public | BindingFlags.Instance); 
string[] fields = (string[])fieldsProperty.GetValue(record, null); 

編輯:

出現此庫有,讓您文件讀入到一個DataTable而不是方法,這似乎是他們推薦的方法。 this page上顯示的示例是:

DataTable dt = engine.ReadFileAsDT("test.txt"); 

這可能比使用反射更簡單和更快。

+0

這是一個小改動。由於我使用字段而不是屬性,我需要使用FieldInfo和GetField()。 – Ferruccio 2010-02-11 05:38:04

+0

我正在處理的一些文件可能變得非常大,我寧願在內存中沒有兩個副本(DataTable +我的數據結構)。然而,看DataTable讓我覺得用它來存儲數據可能更合適。所以我最終可能會重構使用DataTable,並能夠使用更簡單的解決方案。 – Ferruccio 2010-02-11 05:52:02

1

老實說,我能想到的最簡單的方法就是使用IronPython。構造一串代碼並將其傳遞給一個python引擎。我們用DLR和IronPython取代了一噸反射。

或者正如你所說,你可以反思。

編輯:反映意見: 您只需要包含2個鐵蟒組件作爲參考。這並不難。老實說。它不是關於安裝船載其他東西。

+1

你不可能是認真的。 「最簡單」的方法是安裝,學習和部署一種全新的語言,而不是寫2行反思? – Aaronaught 2010-02-11 04:53:23

+0

我從來沒有做過這樣的事情,但我已經安裝並部署了IronPython。我以前使用過Python。我以前從未使用過反射。所以在我的情況下,這將是最簡單的。 :)這都是一個角度問題。 – Dave 2010-02-11 05:02:29

+0

@Dave:當你只有一把錘子時,一切看起來都像釘子。國際海事組織已經安裝了一個特定工具的事實並不是提供依賴於非標準工具的答案的正當理由,而且OP很可能不會*具有。 **尤其是當它是一個反射問題時,它是關於簡單方法或屬性訪問的。 – Aaronaught 2010-02-11 05:17:37

0

在您的代碼中聲明類。這裏不需要使用反射。

+0

這是我原來的做法。問題是分隔符和引號字符是使用屬性設置的,在實例化ImportClass對象後似乎沒有辦法設置它們。 – Ferruccio 2010-02-11 05:28:44

相關問題