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;

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

4

2 回答 2

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;
}
于 2013-02-01T04:12:53.740 回答
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每次创建都会导致内存泄漏

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

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

于 2013-02-01T04:40:03.877 回答