Saving settings in user.config This question came up today on StackOverflow. I find it more unfortunate than (as some others said) idiotic. And it recalled an old function I have which I just remembered.

I have a user.config file which has some settings which can be updated through user action. My rationale was "if the setting is changed, it should be saved." So I made a static class to cover for those settings so as not to handle the operations each time. And I came up with this:

public static class UserSettings
{
    public static string ProcessPath
    {
        get { return _processPath; }
        set 
        { 
            _processPath = Settings.Default.ProcessPath = value;
            Settings.Default.Save();
        }
    }
    //Other functions and properties
}


Yes, I know, it reeks. I feel shame. I want to make this right. I'm thinking this:


the class is static, it should at least be a singleton;
the property should itself not be static;
there's no point in saving the settings every time, just on closing the app, and that would basically be safe in a destructor for the class be best suited for a dedicated function called SaveSettings. Any other object can call it when they see fit, no surprise effects. (further evidence of the need for a singleton).


Are these good intentions in the right direction?
First, I think making it a singleton would be a mistake (singleton usually is). At best it would be extra work with zero benefit. At worst, it's a handicap, such as when/if you decide to support two top-level windows with independent settings for each.

Second, I think I'd add a Boolean named dirty (or something similar). When you set the value, dirty is set to true. When you save the value, you check if dirty is true, and only write out the value if it is (then you set dirty to false).

Personally, I'd probably change it from a static class named ProcessPath to a normal class named (something like) config_string, with an instance for ProcessPath, and a the possibility for other instances holding other strings. To do that, you'd pass Settings.Default.ProcessPath as a parameter when you construct the object.