以编程方式确定设置是按用户还是按应用程序

Programatically determine if settings is per User or per Application

给定任意设置参数 EG Properties.Settings.Default.ArbitraryParam 您能否从应用程序内部以编程方式判断这是每个用户还是每个应用程序设置?

或者,鉴于每个应用程序设置是只读的,防止尝试写入每个应用程序设置的最佳做法是什么?或者除了调用 Properties.Settings.Default.Save() 时未更新的值之外什么都不会发生?

如果你想确定它们是用户范围的还是应用程序范围的,你可以写一点扩展方法...

public static class SettingsExtensions
{
    public bool IsUserScoped(this Settings settings, string variableName)
    {
        PropertyInfo pi = settings.GetType().GetProperty(variableName, BindingFlags.Instance);

        return pi.GetCustomAttribute<System.Configuration.UserScopedSettingAttribute>() != null;
    }
}

然后调用:

Settings.Default.IsUserScoped("SomeVariableName");

如果您想从 属性 中获取实际名称,您可以采取更多技巧,但它显示了一种方法。另一种方法是确定 属性 是否同时包含 getset 访问器(用户范围)或仅包含 get (应用程序范围)。

打开Settings.Designer.cs文件就很清楚了,这里是我的示例文件:

[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {

    private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

    public static Settings Default {
        get {
            return defaultInstance;
        }
    }

    [global::System.Configuration.UserScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.DefaultSettingValueAttribute("blah")]
    public string UserSetting {
        get {
            return ((string)(this["UserSetting"]));
        }
        set {
            this["UserSetting"] = value;
        }
    }

    [global::System.Configuration.ApplicationScopedSettingAttribute()]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Configuration.DefaultSettingValueAttribute("hardy har har")]
    public string AppSetting {
        get {
            return ((string)(this["AppSetting"]));
        }
    }
}

注意到属性了吗?它们可用于确定有关属性的信息。

然而,另一个好方法是,如果你写

Settings.Default.SomeAppSetting = some_value;

由于没有设置访问器,您将遇到编译器错误。