C# 如何将自定义类保存/序列化到设置文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1321248/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 15:07:00  来源:igfitidea点击:

How do I save/serialize a custom class to the settings file?

c#visual-studiosettings

提问by Calanus

I have a small class that holds two strings as follows:

我有一个包含两个字符串的小类,如下所示:

    public class ReportType
    {
        private string displayName;
        public string DisplayName
        {
            get { return displayName; }
        }

        private string reportName;
        public string ReportName
        {
            get { return reportName; }
        }

        public ReportType(string displayName, string reportName)
        {
            this.displayName = displayName;
            this.reportName = reportName;
        }
    }

I want to save an instance of this class to my settings file so that I can do the following:

我想将此类的一个实例保存到我的设置文件中,以便我可以执行以下操作:

ReportType reportType = Settings.Default.SelectedReportType;

Googling seems to suggest that it is possible but there doesn't appear to be a clear guide anywhere for me to follow. I understand that some serialization is required but don't really know where to begin. Also, when I go into the Settings screen in Visual Studio and click "browse" under the Type column there is no option to select the current namespace which contains the ReportType class.

谷歌搜索似乎表明这是可能的,但似乎没有任何地方可供我遵循的明确指南。我知道需要一些序列化,但真的不知道从哪里开始。此外,当我进入 Visual Studio 中的“设置”屏幕并单击“类型”列下的“浏览”时,没有选择包含 ReportType 类的当前命名空间的选项。

采纳答案by Calanus

OK I think that I have eventually worked it out. The first thing to do is to add the following attributes to each property of the ReportType class that needs to be serialised and inherit the class from ApplicationSettingsBase:

好吧,我想我最终已经解决了。首先要做的是在需要序列化的ReportType类的每个属性中添加以下属性,并从ApplicationSettingsBase继承该类:

    public class ReportType : ApplicationSettingsBase
    {
        private string displayName;
        [UserScopedSetting()]
        [SettingsSerializeAs(System.Configuration.SettingsSerializeAs.Xml)]
        public string DisplayName
        {
            get { return displayName; }
        }

..............

………………

and then, once you have rebuilt your assembly (important!) you can go into the settings screen and click browse and then type your namespace and class name in the text box at the bottom (e.g. Label_Creator.ReportType). The namespace and class name do notappear in the tree and so this part is not exactly obvious what you need to do which is why it is a bit confusing....

然后,一旦您重新构建了您的程序集(重要!),您可以进入设置屏幕并单击浏览,然后在底部的文本框中键入您的命名空间和类名(例如 Label_Creator.ReportType)。命名空间和类名没有出现在树中,所以这部分不是很明显你需要做什么,这就是为什么它有点混乱......

回答by Charlie

How about creating a static method which returns an instance of ReportType containing data from the config file. It's simpler and I don't think serializing is necessary.

如何创建一个静态方法,该方法返回包含配置文件中数据的 ReportType 实例。它更简单,我认为不需要序列化。

public class ReportType
{
  public static ReportType GetDefaultSelectedReportType()
  {
    string displayName = ConfigurationManager.AppSettings["DefaultDisplayName"];
    string reportName = ConfigurationManager.AppSettings["DefaultReportName"];
    return new ReportType(displayName, reportName);
  }
  .
  .
  .
}

回答by abatishchev

Just a bit more clear code then Charlie's

只是比查理更清晰的代码

public class ReportType
{
  public static ReportType CreateDefaults()
  {
    return new ReportType
    {
       DisplayName =  ConfigurationManager.AppSettings["DefaultDisplayName"],
       ReportName = ConfigurationManager.AppSettings["DefaultReportName"]
    };
  }
}

回答by guyarad

@Calanus solution did not work for me as-is (on Visual Studio 2015). The missing step is actually setting or getting from the actual settings. As for the original question, implementing a simple POCO can be achieved like this:

@Calanus 解决方案对我来说并不适用(在 Visual Studio 2015 上)。缺少的步骤实际上是设置或从实际设置中获取。至于原来的问题,实现一个简单的 POCO 可以这样实现:

[Serializable]
public class ReportType
{
    public string DisplayName { get; set; }
    public string ReportName { get; set; }

    public ReportType() { }

    public ReportType(string displayName, string reportName)
    {
        DisplayName = displayName;
        ReportName = reportName;
    }
}

// the class responsible for reading and writing the settings
public sealed class ReportTypeSettings : ApplicationSettingsBase
{
    [UserScopedSetting]
    [SettingsSerializeAs(SettingsSerializeAs.Xml)]
    [DefaultSettingValue("")]
    public ReportType ReportType
    {
        get { return (ReportType)this[nameof(ReportType)]; }
        set { this[nameof(ReportType)] = value; }
    }
}

I have used for actually serialization a list:

我已经用于实际序列化列表:

[Serializable]
public class Schedule
{
    public Schedule() : this(string.Empty, DateTime.MaxValue)
    {
    }

    public Schedule(string path, DateTime terminationTime)
    {
        path = driverPath;
        TerminationTime = terminationTime;
    }

    public DateTime TerminationTime { get; set; }
    public string Path { get; set; }
}

public sealed class Schedules : ApplicationSettingsBase
{
    [UserScopedSetting]
    [SettingsSerializeAs(SettingsSerializeAs.Xml)]
    [DefaultSettingValue("")]
    public List<Schedule> Entries
    {
        get { return (List<Schedule>)this[nameof(Entries)]; }
        set { this[nameof(Entries)] = value; }
    }
}

Instantiate a Schedules (ReportTypeSettings) object. It will automatically read the settings. You can use Reload method to refresh. For instance:

实例化一个 Schedules (ReportTypeSettings) 对象。它会自动读取设置。您可以使用 Reload 方法进行刷新。例如:

ReportTypeSettings rts = new ReportTypeSettings();
rts.Reload();
rts.ReportType = new ReportType("report!", "report1");
rts.Save();

IMPORTANT NOTES:

重要说明

  1. Note that UserScoped is intentionally used. ApplicationScoped behaves differently, so make sure you know what you are doing.
  2. The members are public (including the setter), and there's a default c'tor even though it was needed by the code. However, serialization using XMLdidn't work properly. Due to time constraints I didn't investigate.
  3. You can change serialization to binary format as well. It will use BASE64 to store the data.
  4. All the settings is stored in LOCAL APP DATA folder, in a text file.
  1. 请注意,UserScoped 是有意使用的。ApplicationScoped 的行为有所不同,因此请确保您知道自己在做什么。
  2. 成员是公共的(包括 setter),即使代码需要它,也有一个默认的 c'tor。但是,使用 XML 的序列化无法正常工作。由于时间关系,我没有去研究。
  3. 您也可以将序列化更改为二进制格式。它将使用 BASE64 来存储数据。
  4. 所有设置都存储在 LOCAL APP DATA 文件夹中的文本文件中。