2012-06-15 192 views
0

[編輯以除去我需要訪問.NET屬性(副成員變量)的含義]訪問對象的成員變量值

我試圖創建使用.NET一個設計圖案(用C#編碼的WPF是特定的),一個類的實例(派生自基類)具有可以通過在方法調用中傳遞枚舉值來訪問的成員變量。例如,myObject.GetValueOf(dimensionFields.Latitude)將返回由myObject持有的「緯度」值。顯然,目的是在運行時使用GetValueOf([some enum variable])來訪問任何由枚舉定義的字段值。我還需要相當高的性能,因爲當許多(很容易超過100,000個)對象被繪製到顯示器(通過OpenGL)時,這些值將被訪問。

由於性能要求,我不願意使用反射 - 是一個合理的不情願?

我有一個解決方案,但我的問題是:「是他們更好還是更簡單的方法?」

這是我目前的解決方案:我將爲每個想要訪問的成員變量類型(即一個用於雙精度,一個用於整數,一個用於字符串,一個用於布爾等)創建枚舉。我的對象的基類將具有對應於每種類型變量的字典(例如,Dictionary<FieldsForDoubles, double> m_doubleDict)。 A GetValueOf([some enum value])該方法在基類中將被重載以接受每種類型的枚舉並返回適當的數據類型(例如,public double GetValueOf(FieldsForDoubles field))。派生類可以爲了方便添加實際屬性(例如,Latitude屬性),但這些屬性只會訪問適當的字典。

最後,作爲一個遊覽,我可能會做的字典由一個字符串值,而不是一個枚舉值接近,通過使用someEnumValue.ToString()GetValueOf方法獲得的字典,並提供一個通用的方法(GetVaueOf<type>(string variableName))允許某些派生類未持有變量在當前的枚舉,但有一個非常相似的模式(例如,我可以用GetValueOf<double>([some variable name])訪問使用這種模式的任何變量)

任何人看到這種方法的問題(例如,訪問相當短的字典中不可訪問這筆費用,對不對?)?任何其他的想法如何做到這一點?

在此先感謝。

+1

爲什麼不把所有內容都保存在字典中並將枚舉作爲關鍵字?是否有令人信服的理由讓所有房產都有? – vcsjones

+0

我認爲我的標題和描述可能是誤導性的。通過「財產」我真的只是指任何類的變量。我目前的想法如上所述是按照你的建議使用字典。如果需要,任何相關的屬性都會被派生類添加以便於訪問。 – FTLPhysicsGuy

+0

因此,而不是使用反射,你想重塑它?我不知道反射和使用字典來存儲值之間的性能差異,但我無法想象存在很大的差距。如果速度那麼快,那麼.NET會不會在後端這麼做? – cadrell0

回答

0

如果我走了,只是告訴我,我會刪除。爲什麼數據需要屬性,枚舉和字典?爲什麼不僅僅是vcsjones評論中的字典?您從屬性開始,然後參考字段「字段值的數量」。目前還不清楚你想要什麼。你打算在運行時建立枚舉和屬性 - 如果是的話,你打算怎麼做?

可能的簡化方法。

public class dynamicClass 
{ 
    public Dictionary<string, string> DicString { get; private set; } 
    public Dictionary<string, Int32> DicInt32 { get; private set; } 

    public string GetStringFromKey(string key) { return DicString[key]; } 

我看不到什麼GetStringFromKey帶來了表。

在客戶端DicString [key];與GetStringFromKey(key);

+0

感謝您的回覆。我認爲我的標題和描述可能是誤導性的。通過「財產」我真的只是指任何類的變量。儘管我會添加一個像GetValueOf([some variable])這樣的通用訪問方法,但你的模式與我所想的差不多。 – FTLPhysicsGuy

+2

然後請編輯你的問題。所以大多數人會將財產作爲一個正式的.NET屬性讀取。我沒有看到GetValueOf帶來了什麼? – Paparazzi

+0

好點 - 我按照建議編輯了我的問題 – FTLPhysicsGuy

0

(首先,非答案) 就我個人而言,我將致力於開發一種解決方案來重新創建反射。直接屬性引用總是更快,因爲它們擁有內存地址。任何類型的重定向或查找總是會更昂貴。

(這裏有一個答案) 很顯然,我們不知道你的要求或系統,所以這裏有一個想法。如果你的屬性是在一個枚舉中定義的,那麼理論上它們並不是在運行時創建的。因此,而不是使用字典,爲什麼不使用數組?如果你有

enum 
    prop1 = 0 
    prop2 = 1 
    prop3 = 2 

然後,當用戶通過一個枚舉,用它作爲索引到你的陣列中的所有你需要的是長度爲3的數組。

編輯:如果性能是您的主要驅動力,那麼你就需要爲每個類型變量的不同枚舉,使您的陣列可以是「強」類型(非對象)。您將需要爲每種類型提供不同的功能。所以:

enum intProp 
    prop1 = 0 
    prop2 = 1 
    prop3 = 2 

enum floatProp 
    prop1 = 0 
    prop2 = 1 
    prop3 = 2 

int[] intVals 
float[] floatVals 

fun int getIntProp(intProp p) 
    return intVals[(int)p] 

fun float getFloatProp(floatProp p) 
    return floatVals[(int)p] 

這不是很漂亮,但它應該足夠快以處理100,000個對象。不幸的是,我們必須經常平衡性能和可維護性。這是難看的代碼,但漂亮整潔的代碼幾乎總是會帶來性能問題。

如果你想真正的防雷性能,最好的辦法是去與C++和直接管理地址。