如何将当前类设置为返回类型结果

时间:2013-02-01 04:06:19

标签: c# class

我有这堂课:

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;

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

2 个答案:

答案 0 :(得分: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();
}

P.S。:如果属性getter和setter没有其他逻辑(LoadSettings方法不再存在),您可以使用自动属性:

public string CompanyName { get; set; }

public string CompanyPhone { get; set; }

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

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

答案 1 :(得分: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);

请在此处注意,每次will get the memory leak创建XmlSerializer

  

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

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