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:プロパティのゲッターとセッターに追加のロジックがない場合(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 に答える