2014-07-24 56 views
3

我正在爲C#中的大型遊戲項目製作保存/加載系統。如何驗證保存/加載系統的完整性

每個需要保存的類都實現了一個方法DoSnapshot()

在該方法中,程序員必須爲類中的每個字段調用函數 - 如果應該保存foo,則爲DoSnapshot(foo);如果不應該,則爲Ignore(foo)

我對DoFloat,DoString等許多基本類型以及複雜類型的版本都有DoSnapshot方法。

我有100個類,該項目仍在開發中。

是否可以添加某種驗證,即每個類中的所有字段都用於Snapshot()Ignore()調用中?省略字段會導致錯誤。 驗證可以是運行時或編譯時。我只想在開發過程中使用它,它不會被髮布給用戶。

+0

你看了寫在自定義FXCop規則? http://blogs.msdn.com/b/codeanalysis/archive/2010/03/26/how-to-write-custom-static-code-analysis-rules-and-integrate-them-into-visual-studio- 2010。aspx – JoshBerke

+0

不...無論如何,我們正在使用Visual Studio Express 2010,我不認爲它是受支持的。 –

+0

不是沒有其他工具可以執行靜態代碼分析,並允許您添加自定義規則。我認爲你最好的選擇是提供一個Base DoSnapshot方法,這樣開發人員只需要用屬性標記......你可以輕鬆編寫一個例程,以確保每個需要保存的對象都具有標記爲必需或忽略的所有屬性。開發人員不必實現dosnapshot方法:-) – JoshBerke

回答

1

您可以爲需要保存的字段添加屬性,然後在DoSnapshot方法中循環遍歷類中的每個屬性。當酒店有您要查找的屬性時,請致電Snapshot,否則請致電Ignore

public class SomeClass : SomeBaseClass 
{ 
    [Required] 
    public string Foo { get; set; } 
    public string Bar { get; set; } 

    public override void DoSnapshot() 
    { 
     var properties = this.GetType().GetProperties(); 
     foreach (var property in properties) 
     { 
      var isRequired = property.GetCustomAttributes(typeof (RequiredAttribute), false).Length > 0; 
      if (isRequired) 
      { 
       // Something 
      } 
      else 
      { 
       // SomethingElse 
      } 
     } 
    } 
} 
+0

關鍵是檢查程序員是否已經忘記了一些東西。使用標籤而不是方法調用似乎只能解決問題...... –

+0

在我提供的示例中,所有屬性都被提取,並且可以調用Ignore或Snapshot,因此您可以確保每個字段都被查看。 –

+0

好的,謝謝。那麼也應該有一個Ignore標籤。 無論如何,我需要的是方法調用的驗證。 該示例已簡化。我有大約30個版本的DoSnapshot - DoFloat,DoString等。 –

0

你在做什麼聽起來很像standard .NET serialization/deserialization。你有沒有考慮過讓你的類型[Serializable]/ISerializable

有一些規則定義了默認情況下會序列化的內容以及不會的內容,這意味着您不必手動思考類型的每個屬性和字段,而只需考慮異常,即偏離這些標準規則的屬性和字段。

(例如,你就不必Snapshot()這些屬性/在.NET串行會選擇默認反正連載領域你只需要指定例外:你Ignore有可能會與[NonSerialized]取代。 )


PS:正如您在留言狀態,你已經決定了自己的機制,而不是.net序列。儘管如此,從串行化中獲取一個想法也許還不算太晚:convention over configuration

也就是說,您是否需要處理所有屬性/字段,或只處理不常見的情況,即偏離某些固定的預定義規則的屬性?前者可以更容易地系統地檢查完整的覆蓋範圍(例如通過代碼上的System.Reflection),後者可能爲您節省大量工作並使例外更加清晰。

+0

謝謝,我們認爲,但現在設計已經解決。 –

+0

@ user1919998:增加了一個P.S.到我的答案。往上看。 – stakx

+0

大多數不應該序列化的字段是對其他對象,引用集合,時間片計算或便箋式字段中使用的字段的引用。 –

0

我會做的是創建一個屬性和「標記」每個字段,如果它應該保存或不。然後,在運行時,我會查詢該類使用反射,以獲得所有應該序列化的字段:

public class RandomClass 
{ 
    public string Foo { get; set; } 
    [Ignore] 
    public int Bar { get; set; } 
} 

public class IgnoreAttribute : Attribute 
{ 

} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var properties = typeof(RandomClass).GetProperties() 
         .Where(prop => !prop.IsDefined(typeof(IgnoreAttribute), false)); 
     // Serialize all values 
    } 
}