如何将自定义类保存/序列化到设置文件?
Posted
技术标签:
【中文标题】如何将自定义类保存/序列化到设置文件?【英文标题】:How do I save/serialize a custom class to the settings file? 【发布时间】:2010-11-22 05:12:53 【问题描述】:我有一个包含两个字符串的小类,如下所示:
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;
我想将此类的一个实例保存到我的设置文件中,以便我可以执行以下操作:
ReportType reportType = Settings.Default.SelectedReportType;
谷歌搜索似乎表明这是可能的,但似乎在任何地方都没有明确的指南供我遵循。我知道需要进行一些序列化,但不知道从哪里开始。此外,当我进入 Visual Studio 中的“设置”屏幕并单击“类型”列下的“浏览”时,没有选项可以选择包含 ReportType 类的当前命名空间。
【问题讨论】:
使用可以使用更简单的方法: public string ReportName get;私人套装; -- 如果 .NET 3+ 可用 【参考方案1】:好的,我认为我最终解决了这个问题。首先要做的是在需要序列化的ReportType类的每个属性中添加以下属性,并从ApplicationSettingsBase继承该类:
public class ReportType : ApplicationSettingsBase
private string displayName;
[UserScopedSetting()]
[SettingsSerializeAs(System.Configuration.SettingsSerializeAs.Xml)]
public string DisplayName
get return displayName;
.......
然后,一旦你重建了你的程序集(重要!),你可以进入设置屏幕并单击浏览,然后在底部的文本框中键入你的命名空间和类名(例如 Label_Creator.ReportType)。命名空间和类名不会出现在树中,因此这部分并不完全清楚您需要做什么,这就是为什么它有点令人困惑......
【讨论】:
那你如何初始化属性呢?我试图重现你的步骤,但它一直失败。当我调用(使用您的情况)Settings.Default.ReportType 时,它会因空引用异常而下降...问题可能是我的属性使用 winforms Keys 类而不是例如字符串 这个解决方案对我不起作用,不确定是否是由于发布时存在的 VS 版本。为了他人的利益,我提出了另一个答案。【参考方案2】:@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;
我已经用实际序列化了一个列表:
[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;
实例化一个 Schedules (ReportTypeSettings) 对象。它会自动读取设置。您可以使用 Reload 方法进行刷新。 例如:
ReportTypeSettings rts = new ReportTypeSettings();
rts.Reload();
rts.ReportType = new ReportType("report!", "report1");
rts.Save();
重要提示:
-
请注意,有意使用 UserScoped。 ApplicationScoped 的行为不同,因此请确保您知道自己在做什么。
成员是公共的(包括setter),并且有一个默认构造函数,即使代码需要它。但是,使用 XML 的序列化无法正常工作。由于时间限制,我没有进行调查。
您也可以将序列化更改为二进制格式。它将使用 BASE64 来存储数据。
所有设置都存储在 LOCAL APP DATA 文件夹中的文本文件中。
【讨论】:
c'tor = 构造函数【参考方案3】:如何创建一个返回包含配置文件数据的 ReportType 实例的静态方法。它更简单,我认为不需要序列化。
public class ReportType
public static ReportType GetDefaultSelectedReportType()
string displayName = ConfigurationManager.AppSettings["DefaultDisplayName"];
string reportName = ConfigurationManager.AppSettings["DefaultReportName"];
return new ReportType(displayName, reportName);
.
.
.
【讨论】:
作为最后的手段,我可以这样做,但实际上我有许多不同的报告要保存设置,而且我可能还会增加 ReportType 类以存储比此处显示的两个更多的字符串。 有一个设置助手类,每个报告都有扩展方法吗?我认为配置中的序列化对象看起来有点奇怪。【参考方案4】:比Charlie's更清晰的代码
public class ReportType
public static ReportType CreateDefaults()
return new ReportType
DisplayName = ConfigurationManager.AppSettings["DefaultDisplayName"],
ReportName = ConfigurationManager.AppSettings["DefaultReportName"]
;
【讨论】:
实际上,我担心我会撤消我的投票。由于这个对象应该保存配置数据,我认为它应该是不可变的,这样它的状态就不能在构造后改变。所以我的回答更好;) @Charlie - 除了语法之外,这与您的 anwser 有何不同?我错过了“不可变”部分——这不应该是get
属性吗?以上是关于如何将自定义类保存/序列化到设置文件?的主要内容,如果未能解决你的问题,请参考以下文章
如何将自定义类导入 Flex 中的 mxml 文件? (动作脚本 3)