2010-08-17 99 views
6

這是一個C#winforms應用程序。如何在另一個對象中存儲對象屬性的引用?

前言:

我創建一個表單,允許用戶從現有的MySQL或SQL Server數據庫中的數據導入到我的SQL Server數據庫。這使用戶可以快速導入IP地址和其他數據,而無需通過控件重新輸入IP地址和其他數據。

實施例:

簡體,我有兩個目的,FieldObjectSensorObject。存在FieldObject以存儲源和目標數據庫字段名稱和類型。 SensorObject是我稍後從數據庫中的記錄填充的對象。爲了簡單起見,我省略了與問題無關的類型處理和其他功能。 (對於DestinationField的數據僅限於我提供用戶的列表,以及來自節目內的數組或列表。)在這裏是兩個的一個示例:

public class FieldObject 
{ 
    public string DestinationField {get; set;} 
    public string SourceField {get; set;} 
} 

public class SensorObject 
{ 
    public string Name {get; set;} 
    public string IPAddress {get; set;} 
} 

問題:

當用戶填充FieldObject的各個字段時,我使用這些信息來填充目標數據庫,儘管我有一個大的switch語句來檢查目標字段名稱,以知道它屬於哪個屬性SensorObject

例如:

// Reader is a SqlDataReader with the prerequisite database connection 
FieldObject myField = new FieldObject 
    { 
     DestinationField = "name", 
     SourceField = "proprietary" 
    }; 
SensorObject mySensor = new SensorObject(); 
switch (myField.DestinationField) 
{ 
    case "name": 
     mySensor.Name = Convert.ToString(Reader[myField.DestinationField]); 
     break; 
    case "ip_address": 
     mySensor.IPAddress = Convert.ToString(Reader[myField.DestinationField]); 
     break; 
} 

正如你可以看到它需要更多的冗餘代碼來處理的對象更多的屬性。

問:

我想存儲的SensorObject屬性的某種方式,數據屬於,以便在列表迭代FieldObjects的時候,我可以有效地消除switch語句。

喜歡的東西:

foreach(FieldObject f in myFieldList) 
{ 
    mySensor(f.mySensorField) = Convert.ToString(Reader[f.DestinationField]); 
} 

我不能肯定什麼技術在C#本身借給這種應用。我已經研究過參考價值和反思,而且都不合適。

我很感謝任何見解和建議,甚至重新考慮這種方法。

+0

你可以使用ORM來解決這個問題,所以你不必編寫這個冗餘代碼? – 2010-08-17 20:36:18

+0

對象關係映射?我懷疑如果我不需要查看「ORM」是什麼,我可能可以使用它。 :)對不起,這裏仍然是新手! – JYelton 2010-08-17 20:40:42

+0

看看NHibernate:http://nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx從長遠來看,ORM消除了使用關係數據庫的大部分痛苦,然而它們需要一些工作開始。 – Zebi 2010-08-17 20:46:32

回答

2

你必須使用反射來做到這一點。 應該結束了,就像這樣:

var sensorFields = typeof(SensorObject).GetProperties() 
foreach(var field in fields) 
{ 
    var info = sensorFields.First(sensorField => sensorField.Name == field.Name); 
    var value = Convert.ToString(Reader[field.Destination]); 
    info.SetValue(sensorObj, value, new object[0]); 
} 

的GetProperties,用於獲取可用於設置值的每個屬性的屬性信息。

當然,可以緩存屬性信息。只需寫一次,一旦運行就重構。不要太複雜太多,這被稱爲過早優化,並導致直接地獄;)

+0

這看起來非常有幫助,它有助於讓有人瞭解反射及其用途以指出正確的方向! – JYelton 2010-08-17 20:38:07

+0

如果用'lookup.Add(field.Name,field)'替換循環內容,其中'lookup'是一個'Dictionary ',這就是您稍後需要緩存這些結果的全部內容。 – 2010-08-17 20:40:53

+0

我不清楚'Reader [myField.DestinationField]是什麼,但我不確定你需要將它轉換爲字符串。或者,如果你這樣做了,我會認爲你只需調用'x.ToString()'而不是使用'Convert.ToString(x)'。 – 2010-08-17 20:43:22

1

實際上,反射並不是一個壞主意,特別是如果您爲每個屬性名稱填入PropertyInfo實例的字典。

1

你可以用反射做到這一點。你得到問題名稱的屬性的PropertyInfo,獲取setter的MethodInfo,然後調用它。

雖然可以存儲通過名稱存儲的值的關聯數組(Dictionary或HastTable等),如果適當,這將更容易處理。

+1

在PropertyInfo中調用'GetSetMethod'可能有意義,它會向設置者本身返回一個'MethodInfo'。 – 2010-08-17 20:45:44

+0

@Steven,對吧。當我開始回答問題時,我忘記了什麼時候更新了對象:)修正了,謝謝。 – 2010-08-17 20:51:59

+1

只需使用PropertyInfo.SetValue(Object,Object,Object []) – Zebi 2010-08-17 21:03:19

相關問題