2017-06-20 71 views
0

這是一個普遍的問題,我相信它已經解決了。如何獨立於名稱更改重建類名稱引用?

我有幾個類(一個實體系統的組件),我想保存對文件(字符串或標誌)中的類的引用作爲保存/加載系統的一部分。但是隨後我希望能夠隨着時間的推移改變C#中類的名稱,並且在下次自動重新構建正確的數據,而無需手動遷移數據。

目前我想有辦法做到這一切全部自動,假設所有在C#中引用的類不會立即改變。我可以做字符串檢查以消除可以解決的引用 - 然後顯示一個UI彈出窗口來解決類似於「哦,Renderable類已更改,它看起來像模型的級別數據都指向此,是否它們同班?「。我還可以使用Reflection來查找函數名稱,以構建相關類的「元數據配置文件」(與其名稱標籤不同),因此數據問題不會與GetType()。GUID或其他任何(初始化順序?)綁定。

如果我創建了一些簡單類型的數據庫,那麼將在第一個會話中生成標誌值,然後在實際級別文件中查找並針對該特定級別文件進行重新洗牌..但這是它變得複雜的地方,這不好或有幫助。如果數據庫文件丟失了,在加載級別文件時有200多種類型需要解決。

也許有一個更簡單的方法。但就信息而言,只有cpu可能知道的實際類成員/字段,而沒有明確地指定和關注它。沒有辦法提出這種數據問題的錯誤,沒有驗證檢查。

我的一個想法是在定義類時使用互斥標籤 - 強制它們使用模板參數T繼承IDummy,其中T來自其他虛擬接口標籤的列表,因此您應該選擇類似於枚舉的東西然後將其添加到字典(鍵入爲鍵)以拋出進一步的錯誤,以防止程序在類定義和類功能(與其名稱標籤無關)之間沒有一致的映射時運行。然後,如果我想永久刪除一個班級的數據 - 我只是將其「標籤」列入黑名單。

我正在通過依賴於C#反射/元數據的模板技巧來做所有這些事情。這是可能的,我知道它是。

對於每個輕量級對象(實體),所有存儲的都是一個id和一個標誌值。

+2

首先,這聽起來*可怕*;爲什麼不只是序列化到JSON?沒有包含類型信息 – BradleyDotNET

+1

保存數據總是意味着你有這個問題。這是關於舊信息沒有被鏈接到新信息。 JSON會給出同樣的焦慮,因爲在下一次運行的程序中沒有繼續做某些事情(因爲類名稱標籤已經改變,因此所有事情都從中衍生出來) 這是一個合法的問題來解決(會話之間的數據和程序結構變化)。 如果您需要區分正在處理的類別/類型,您總是需要類型信息! 嗯我想我應該停止避免顯式標誌/散列。 – brear888

+0

僅僅因爲你*可以*做到這並不意味着你*應該*做到這一點。退後一步,思考你實際想要達到的目標。有沒有更好的辦法?更合理的東西?你已經聽說過一些模式?如果我懷疑它是否需要,你會介紹**很多複雜性。 – bc004346

回答

0

使用反射,您可以潛入任何程序集並提取您想要的任何東西,這裏是提取ClassNames的示例。

var asm = Assembly.Load("Some.Assembly.Name"); 
    var nameSpace = "Some.Namespace.Name"; 

    var classes = asm.GetTypes().Where(p => 
     p.Namespace == nameSpace && 
     p.Name.Contains("ClassNameFilter") 
    ).ToList(); 
+0

這是一個「會話之間的數據」問題,而不是「將班級字符串化」問題。當類名更改時,所有以前的類名都可以進行比較 - 但我可能想要旋轉類名或將其更改回來 - 這表示您未在解決方案中考慮的循環引用問題。 – brear888

0

好吧,我現在要做的是一個「骯髒」的解決方案,但它是細緻的人們可以忍受的事情之一。

我只是添加一個獨立於會話/標籤的標識符。我打算使用一個模板參數看起來更清潔..但我需要的是指定1,2或3等作爲某種編譯時間id爲我想區分的類(這些是索引查找實際使用的位標值)

因此,在類的第一行中,我現在將類型ID的靜態int。還有很多東西(模板基類,單例,初始化順序黑客),但至少現在它很好,很簡潔。唯一的是我必須爲每個班級指定一個數字。 (程序絕對必須獨立於類名稱)。

元數據的想法是一個糟糕的主意,因爲如果我想克隆一個類/組件,沒有辦法正確區分它(除了可能的類型名稱)。所以也許它可以工作。

我不想涉及一個「數據庫」(一個文本文件映射會做 - 它從編譯器的命名順序中逃脫初始化順序),這可能是一個好主意,以避免它,只是對於那些角落案例(我想突然改變所有類名的1000個遊戲對象的數據庫)

這只是一個固有的信息缺失問題。幾乎唯一的解決方案是明確它是哪個類(在所有其他上下文之外),併爲重複的類型標識符引發錯誤。

這並不像我們不能推斷出某些關於數據變化的程序行爲。程序仍然應該能夠找出什麼是什麼......除了像一個組件類的情況與另一個組件類具有完全相同的字段和成員,所以它們除了類名外都「看起來相同」 ,當解決它是什麼類時,我們不能依賴它。 (在我可以隨時更改的場景中)。

+0

在會話/名稱之間避免一致的類標識符是現代工業編程STILL尚未解決的教條式OOP問題。所以從根本上講,這是一個相當直接和可以理解的問題。在C#中,您不能簡單地將具有值的類定義爲模板參數。 – brear888