我有这堂课:
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;
我可以直接分配属性而无需维护此代码吗?
答案 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
保持为静态。