2012-02-18 36 views
1

我試圖維護一個配置字典。如何將字典序列化爲XML文件?

這是我的抽象類。

[Serializable] 
public abstract class Configuration 
{ 
} 

這裏是一個具體的類(目前,我只有這個類)。

[Serializable] 
public class BinaryProblemConfiguration : Configuration 
{ 
    [XmlAttribute] 
    public decimal MinValue { get; set; } 
    [XmlAttribute] 
    public decimal MaxValue { get; set; } 
} 

我有一個類,其中包含Dictionary的配置級別。

  • 第一個參數是配置的名稱。當name=""表示默認配置。
  • 等級表示困難。有三個級別:簡單,中等和困難。
  • 第三個是配置。
/// <summary> 
/// The abstract level configuration allows descendent classes to configure themselves 
/// </summary> 
public abstract class LevelConfiguration 
{ 
    private Dictionary<string, Dictionary<Levels, Configuration>> _configurableLevels = new Dictionary<string, Dictionary<Levels, Configuration>>(); 

    /// <summary> 
    /// Adds a configurable level. 
    /// </summary> 
    /// <param name="level">The level to add.</param> 
    /// <param name="problemConfiguration">The problem configuration.</param> 
    protected void AddConfigurableLevel(string name, Levels level, Configuration problemConfiguration) 
    { 
     if (!_configurableLevels.ContainsKey(name)) 
     { 
      _configurableLevels.Add(name, new Dictionary<Levels, Configuration>()); 
     } 

     _configurableLevels[name].Add(level, problemConfiguration); 
    } 

    /// <summary> 
    /// Returns all the configurable levels. 
    /// </summary> 
    /// <param name="level"></param> 
    protected void RemoveConfigurableLevel(string name, Levels level) 
    { 
     _configurableLevels[name].Remove(level); 
    } 

    /// <summary> 
    /// Returns all the configurable names. 
    /// </summary> 
    /// <returns></returns> 
    public IEnumerable<string> GetConfigurationNames() 
    { 
     return _configurableLevels.Keys; 
    } 

    /// <summary> 
    /// Returns all the configurable levels. 
    /// </summary> 
    /// <returns></returns> 
    public IEnumerable<Levels> GetConfigurationLevels(string name) 
    { 
     return _configurableLevels[name].Keys; 
    } 

    /// <summary> 
    /// Gets the problem configuration for the specified level 
    /// </summary> 
    /// <param name="level">The level.</param> 
    /// <returns></returns> 
    public Configuration GetProblemConfiguration(string name, Levels level) 
    { 
     return _configurableLevels[name][level]; 
    } 
} 

這是創建一些配置中的類。我正在創建三個默認配置和兩個習慣。

public class AdditionLevelConfiguration : LevelConfiguration 
{ 
    public AdditionLevelConfiguration() 
    { 
     AddConfigurableLevel("", Levels.Easy, GetEasyLevelConfiguration()); 
     AddConfigurableLevel("", Levels.Medium, GetMediumLevelConfiguration()); 
     AddConfigurableLevel("", Levels.Hard, GetHardLevelConfiguration()); 

     AddConfigurableLevel("config2", Levels.Easy, GetEasyLevelConfiguration()); 
     AddConfigurableLevel("config2", Levels.Medium, GetMediumLevelConfiguration()); 

     var configs = this.GetProblemConfiguration("config2", Levels.Medium); 
     var configs2 = this.GetProblemConfiguration("", Levels.Easy); 
    } 

    protected Configuration GetHardLevelConfiguration() 
    { 
     return new BinaryProblemConfiguration 
     { 
      MinValue = 100, 
      MaxValue = 1000, 
     }; 
    } 

    protected Configuration GetMediumLevelConfiguration() 
    { 
     return new BinaryProblemConfiguration 
     { 
      MinValue = 10, 
      MaxValue = 100, 
     }; 
    } 

    protected Configuration GetEasyLevelConfiguration() 
    { 
     return new BinaryProblemConfiguration 
     { 
      MinValue = 1, 
      MaxValue = 10, 
     }; 
    } 
} 

我打算將這些配置寫入XML文件。我正在考慮將它們序列化,但它會引發一個錯誤。我該怎麼辦?

+1

Codereview用於獲取工作代碼的評論。 「我怎麼做X」的問題屬於Stack Overflow。 – sepp2k 2012-02-19 14:36:04

回答

3

您可能會考慮的另一個選擇是使用DataContractSerializer。我能夠以這種方式序列化你的字典詞典。

事情要記住,如果你走這條路線:

  • 您必須添加不同的屬性。具體而言,您需要DataContract屬性上的類型和DataMember。
  • 您需要確保所有屬性都有setter,即使setter最終是私有的。
  • 創建DataContractSerializer時,需要確保知道您的所有類型。賦予它字典的類型可以處理字符串,級別和配置,而不是BinaryProblemConfiguration。附加的類型信息可以通過額外的構造函數重載提供。

例子:

var dict = new Dictionary<string,Dictionary<Levels,Configuration>>(); 
var wtr = XmlWriter.Create (Console.Out); 
var dcSerializer = new DataContractSerializer (dict.GetType(), new [] {typeof (BinaryProblemConfiguration)}); 
dcSerializer.WriteObject (wtr, dict); 

如果你做到上面,你也可以切換到DataContractJsonSerializer後更加緊湊JSON格式,如果你喜歡(假設XML不是硬性要求,當然)。