【问题标题】:How can I save a copy of Properties.Settings.Default to a variable?如何将 Properties.Settings.Default 的副本保存到变量中?
【发布时间】:2013-03-02 07:09:52
【问题描述】:

我在一个选项对话框中有一个“恢复默认值”按钮,我想恢复仅在此表单中受影响的值,而不是整个 Properties.Settings.Default

所以我尝试了:

var backup = Properties.Settings.Default;
Properties.Settings.Default.Reload();
overwriteControls();
Properties.Settings.Default = backup;

但不幸的是,这不起作用,因为备份似乎在Reload() 也发生了变化?为什么以及如何正确执行此操作?

【问题讨论】:

  • 您只是保存对设置对象的引用,而不是它的副本。因此,Reload 更新唯一可用的对象,您可以通过这两个变量看到。
  • 所以这是一个指向 Properties.Settings.Default 的指针还是什么?实际上我没有使用合成器作为指针......这真的让我感到困惑......我将如何保存它的副本?
  • .NET 使用“引用类型”和“值类型”的概念。类实例是“引用类型”,变量指向它们。它是一个指针,但由运行时管理。为了复制一个对象,它必须支持某种形式的“克隆”——msdn.microsoft.com/en-us/library/system.icloneable.aspx IClonable 接口用于此目的。但是,设置对象没有实现它,我不知道如何在没有进一步研究的情况下解决这个问题,这就是为什么我没有提出这个作为答案,只是指出你的代码在哪里以及为什么失败。

标签: c# winforms settings


【解决方案1】:

Settings 类使用单例模式,这意味着它们在任何时候都只能是设置的一个实例。因此,制作该实例的副本将始终引用同一个实例。

理论上,您可以使用反射遍历 Settings 类中的每个属性并提取如下值:

        var propertyMap = new Dictionary<string, object>();

        // backup properties
        foreach (var propertyInfo in Properties.Settings.Default.GetType().GetProperties())
        {
            if (propertyInfo.CanRead && propertyInfo.CanWrite && propertyInfo.GetCustomAttributes(typeof(UserScopedSettingAttribute), false).Any())
            {
                var name = propertyInfo.Name;
                var value = propertyInfo.GetValue(Properties.Settings.Default, null);
                propertyMap.Add(name, value);
            }
        }

        // restore properties
        foreach (var propertyInfo in Properties.Settings.Default.GetType().GetProperties())
        {
            if (propertyInfo.CanRead && propertyInfo.CanWrite && propertyInfo.GetCustomAttributes(typeof(UserScopedSettingAttribute), false).Any())
            {
                var value = propertyMap[propertyInfo.Name];
                propertyInfo.SetValue(Properties.Settings.Default, value, null);                    
            }
        }

不过,这有点棘手,如果您的设置很复杂,可能需要做一些工作。您可能需要重新考虑您的策略。您只能在按下 OK 按钮后提交这些值,而不是将这些值恢复为默认值。无论哪种方式,我认为您将需要逐个属性地将每个值复制到某个临时位置。

【讨论】:

  • 仅在按下 OK 按钮时提交值正是我想要做的。但是我需要一种简单的方法来将控件重置为默认值,当按下 "Restore Defaults" 时。所以我想我备份设置,然后执行Reload(),使用该值重置控件,然后恢复备份。但也许使用checkBox1.Checked = bool.Parse((string)settings.Properties["setting1"].DefaultValue); 之类的东西会更好,但这看起来有点糟糕:-/
  • 我将您的示例用于单元测试,我不希望单元测试覆盖现有设置。
猜你喜欢
  • 1970-01-01
  • 2018-06-15
  • 2018-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-21
  • 2013-04-20
  • 2016-04-16
相关资源
最近更新 更多