0

.NET XmlSerializer クラスを使用して、XML ファイルとの間でシリアル化および逆シリアル化できるクラスを作成しようとしています。保存機能 ("SaveSettings") は動作するようになりましたが、読み込み機能はそれほど単純ではありません。

現在、ロード関数を機能させるために、クラス変数の参照を関数に渡す必要があります("LoadSettings2") 理想的なのは、「this」キーワード("LoadSettings")を使用することだけです。ファイル パスを渡すだけでよい LoadSettings 関数を作成しますか?

Program.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");
    }
}

ApplicationSettings.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 を使用して実行しました。パブリック変数のみがコピーされ、クラスにはさらにテストが必要だと思います。10,000 回の反復を実行するのに約 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;
}

それ以外の場合は、別のインスタンスに逆シリアル化し、メンバーごとに値を現在のインスタンスにコピーする必要があります。usingブロックを使用したほうがよいことに注意してくださいStreamReader-Dispose呼び出しにより、ファイルハンドルが確実に解放されます。

于 2012-08-06T09:20:50.983 に答える
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 に答える
0

LoadSettings()メソッドを作成して、static次のように呼び出してみませんか。

ApplicationSettings applicationSettings = ApplicationSettings.LoadSettings();
于 2012-08-06T09:21:44.670 に答える