2013-02-01 37 views
1

我有这个类:我怎么当前类设置为返回类型的结果

using System.IO; 
using System.Xml.Serialization; 

    namespace ssscc.Settings 
    { 
     public class AppSettings 
     { 
     private string _companyName; 
     public string CompanyName 
     { 
      set { _companyName = value; } 
      get 
      { 
      if (string.IsNullOrWhiteSpace(_companyName)) 
      { 
       LoadSettings(); 
      } 
      return _companyName; 
      } 
     } 

     private string _companyPhone; 
     public string CompanyPhone 
     { 
      set 
      { 

      _companyPhone = value; 
      } 
      get 
      { 
      if (string.IsNullOrWhiteSpace(_companyPhone)) 
      { 
       LoadSettings(); 
      } 
      return _companyPhone; 
      } 
     } 

     private string GetSettingsFile() 
     { 
      var exePath = System.Windows.Forms.Application.StartupPath; 
      var sharedDirectory = Path.Combine(exePath, "shared"); 
      var settingsDirectory = Path.Combine(sharedDirectory, "settings"); 
      var settingsFile = Path.Combine(settingsDirectory, "ssscc.xml"); 

      if (!Directory.Exists(sharedDirectory)) 
      { 
      Directory.CreateDirectory(sharedDirectory); 
      } 

      if (!Directory.Exists(settingsDirectory)) 
      { 
      Directory.CreateDirectory(settingsDirectory); 
      } 

      return settingsFile; 
     } 

     internal void SaveSettings(AppSettings settings) 
     { 
      var serializer = new XmlSerializer(typeof(AppSettings)); 
      using (var stream = File.OpenWrite(GetSettingsFile())) 
      { 
      serializer.Serialize((Stream) stream, (object) settings); 
      } 
     } 

     internal void LoadSettings() 
     { 
      if (!File.Exists(GetSettingsFile())) 
      { 
      return; 
      } 

      var serializer = new XmlSerializer(typeof(AppSettings)); 
      using (var stream = File.OpenRead(GetSettingsFile())) 
      { 
      var appsetting = (AppSettings) serializer.Deserialize(stream); 
      CompanyPhone = appsetting.CompanyPhone; 
      CompanyName = appsetting.CompanyName; 
      } 
     } 

     } 
    } 

我的问题是关于这个代码:

var appsetting = (AppSettings) serializer.Deserialize(stream); 
    CompanyPhone = appsetting.CompanyPhone; 
    CompanyName = appsetting.CompanyName; 

我敢肯定有办法将appsettings直接返回到包含该方法的类,以便我不必循环遍历每个属性,例如:

CompanyPhone = appsetting.CompanyPhone; 
    CompanyName = appsetting.CompanyName; 

我可以直接分配属性而不必维护此代码吗?

回答

1

您正在从文件反序列化过程中获得AppSettings的新实例。你可以使用它,不是吗?尝试用这样的静态工厂方法来替代LoadSettings

internal static AppSettings GetInstance() 
{ 
    if (!File.Exists(GetSettingsFile())) 
     return null; 

    var serializer = new XmlSerializer(typeof(AppSettings)); 
    using (var stream = File.OpenRead(GetSettingsFile())) 
     return (AppSettings)serializer.Deserialize(stream); 
} 

,同时保存设置,你有没有需要通过设置对象作为参数。我想下面的代码应该做的工作:

internal void SaveSettings() 
{ 
    var serializer = new XmlSerializer(typeof(AppSettings)); 
    using (var stream = File.OpenWrite(GetSettingsFile())) 
     serializer.Serialize((Stream)stream, this); 
} 

使用工厂GetInstance方法来初始化设置(当然,作为一个例子):

var s = AppSettings.GetInstance(); 
if (s == null) 
{ 
    s = new AppSettings 
    { 
     CompanyName = "MyCompany", 
     CompanyPhone = "######" 
    }; 
    s.SaveSettings(); 
} 

PS:如果属性的getter和setter没有其他逻辑(LoadSettings方法已不存在),你可以使用自动属性:

public string CompanyName { get; set; } 

public string CompanyPhone { get; set; } 

GetSettingsFile可以声明为static,因为它不运行任何的实例类成员:

private static string GetSettingsFile() 
{ 
    //... 
    return settingsFile; 
} 
+0

这就是我正在寻找伟大的答案! – ErocM

+0

顺便说一句,如果你使用这个,请注意这个问题是有关这些方法:http://stackoverflow.com/questions/14654527/extra-closing-bracket-in-xml – ErocM

1

你真的需要有延迟加载在这里,如果没有,让你的方法明确:

public class AppSettings 
{ 
    private static readonly XmlSerializer Serializer 
        = new XmlSerializer(typeof(AppSettings)); 

    public string CompanyName { get; set; } 
    public string CompanyPhone { set; get; } 

    private static string GetSettingsFile() 
    { 
     return null; 
    } 

    public static void SaveSettings(AppSettings settings) 
    { 
     using (var stream = File.OpenWrite(GetSettingsFile())) 
      Serializer.Serialize(stream, settings); 
    } 

    internal static AppSettings LoadSettings() 
    { 
     if (!File.Exists(GetSettingsFile())) 
      return null; 

     object appsetting = null; 

     using (var stream = File.OpenRead(GetSettingsFile())) 
      appsetting = Serializer.Deserialize(stream); 

     return appsetting as AppSettings; 
    } 
} 

你可以使用:

var setting = AppSettings.LoadSettings(); 

和:

AppSettings.SaveSettings(setting); 

请注意这里,创造XmlSerializer每次will get the memory leak

XmlSerializer的构造函数将通过分析使用反射Person类生成一对从XmlSerializationReader派生类和XmlSerializationWriter。它将创建临时C#文件,将生成的文件编译为临时程序集,然后将该程序集加载到进程中。像这样的代码也相对昂贵。因此,XmlSerializer以每种类型为基础缓存临时程序集。这意味着下次创建Person类的XmlSerializer时,会使用缓存的程序集而不是生成的新程序集。

因此,您应该保持XmlSerializer为静态。

+0

+1伟大的答案!我刚好碰到他的第一个。 – ErocM

相关问题