0

我正在尝试通过使用 .NET XmlSerializer 类创建一个可以序列化和反序列化自身到 XML 文件的类。我可以使用保存功能(“SaveSettings”),但加载功能并不那么简单。

目前我必须将类变量的引用传递给函数以使加载函数工作(“LoadSettings2”)理想的情况是只使用“this”关键字(“LoadSettings”)无论如何创建一个只需要传递文件路径的 LoadSettings 函数?

程序.cs:

class Program
{
    static void Main(string[] args)
    {
        ApplicationSettings appSet = new ApplicationSettings();
        appSet.SourceDirectory = "here";
        appSet.DestinationDirectory = "there";

        appSet.SaveSettings(@"C:\Users\Connor\Desktop\Folder A\a.xml");
        //appSet.LoadSettings(@"C:\Users\Connor\Desktop\Folder A\a.xml"); //Doesn't work
        appSet.LoadSettings2(ref appSet, @"C:\Users\Connor\Desktop\Folder A\a.xml");
    }
}

应用程序设置.cs:

public class ApplicationSettings
{
    //Serialized
    public string SourceDirectory;
    public string DestinationDirectory;

    //Not Serialized
    public void SaveSettings(string filePath)
    {
        XmlSerializer XSerializer = new XmlSerializer(typeof(ApplicationSettings));
        StreamWriter strWrite = new StreamWriter(filePath);

        XSerializer.Serialize(strWrite, this);
        strWrite.Close();
    }

    public void LoadSettings(string filePath)
    {
        XmlSerializer XSerializer = new XmlSerializer(typeof(ApplicationSettings));
        StreamReader strRead = new StreamReader(filePath);

        //Ideal but will not work
        //this = (ApplicationSettings)XSerializer.Deserialize(strRead);
        strRead.Close();
    }

    public void LoadSettings2(ref ApplicationSettings appSettings, string filePath)
    {
        XmlSerializer XSerializer = new XmlSerializer(typeof(ApplicationSettings));
        StreamReader strRead = new StreamReader(filePath);

        appSettings = (ApplicationSettings)XSerializer.Deserialize(strRead);
        strRead.Close();
    }
}

-

- 回答 - -

通过“David M”建议的逐个成员复制来实现它但是通过使用 System.Reflection 来实现,这意味着没有使用变量名。我相信只有公共变量被复制,类需要更多的测试。执行 10k 次迭代大约需要 1.8 秒。

public void LoadSettings(string filePath)
{
    XmlSerializer XSerializer = new XmlSerializer(typeof(ApplicationSettings));
    StreamReader strRead = new StreamReader(filePath);
    ApplicationSettings settingsRead = (ApplicationSettings)XSerializer.Deserialize(strRead);

    foreach (var field in typeof(ApplicationSettings).GetFields())
    {
        field.SetValue(this, field.GetValue(settingsRead));
    }

    strRead.Close();
}
4

3 回答 3

2

改为使用静态工厂方法:

public static ApplicationSettings LoadSettings(string filePath)
{
    XmlSerializer XSerializer = new XmlSerializer(typeof(ApplicationSettings));
    using (StreamReader strRead = new StreamReader(filePath))
    {
        var result = (ApplicationSettings)XSerializer.Deserialize(strRead);
    }
    return result;
}

否则,您将不得不反序列化到另一个实例,并逐个成员将值复制到当前实例。请注意,您最好使用一个usingStreamReader-Dispose调用将确保文件句柄被释放。

于 2012-08-06T09:20:50.983 回答
0

为什么不创建LoadSettings()一个static方法并像这样调用它:

ApplicationSettings applicationSettings = ApplicationSettings.LoadSettings();
于 2012-08-06T09:21:44.670 回答
0

通过“David M”建议的逐个成员复制来实现它但是通过使用 System.Reflection 来实现,这意味着没有使用变量名。我相信只有公共变量被复制,类需要更多的测试。执行 10k 次迭代大约需要 1.8 秒。

public void LoadSettings(string filePath)
{
    XmlSerializer XSerializer = new XmlSerializer(typeof(ApplicationSettings));
    StreamReader strRead = new StreamReader(filePath);
    ApplicationSettings settingsRead = (ApplicationSettings)XSerializer.Deserialize(strRead);

    foreach (var field in typeof(ApplicationSettings).GetFields())
    {
        field.SetValue(this, field.GetValue(settingsRead));
    }

    strRead.Close();
}
于 2012-08-07T00:20:56.270 回答