轻松加载和保存设置,存储为简单类

本文介绍了一种使用类属性作为设置的方法,简化了应用程序设置的管理和存储。通过创建一个类,将设置作为属性,然后利用XML进行保存和加载,可以方便地保存和恢复设置。代码示例展示了如何处理常见的数据类型,如字符串、整数、布尔值、日期时间等,并提供了错误处理。存储位置默认为本地应用数据文件夹,同时支持自定义文件名。
摘要由CSDN通过智能技术生成

目录

介绍

代码很简单

例子

设置类型

存储位置

错误处理

保存类

加载一个类

结论


介绍

在开发应用程序时,我厌倦了为我创建的每个设置添加线条,所以我认为必须有更好的方法来处理它们。这就是结果。

这段代码提供了使用类进行设置。要添加新设置,只需在类中创建一个新属性。设置存储在一个简单的类中,设置是该类中的一个属性。不需要额外的代码来确保它被保存或加载。保护程序将读取所有属性并将它们全部保存到文件中。加载器将创建类,从而设置默认设置。文件中存在的任何值都将应用于该类。最后,返回类以供软件使用。

代码很简单

首先是设置存储空间和设置文件名。人们可以根据需要改变这一点。

接下来,为了保存,将读取所有属性并一一保存到文件中。

对于读取,读取文件,如果名称作为属性存在于settings类中,则将其应用于类。这也可以在settings类中的set { }中进行一些验证。

使用的类可以命名为任何名称,并且可以有多个文件和设置。
此示例使用默认文件名settings.config,但可以使用任何文件名来创建更多文件。

例子

下面是一个简单的settings类示例:

public class Settings
{
    public int Setting1 { get; set; }
    public bool Setting2 { get; set; }
    public double Setting3 { get; set; } = 7.6;
    public DateTime Setting4 { get; set; }
    public string Setting5 { get; set; } = "test";
    public List<string> Setting6 { get; set; } = new List<string>()
                                       { "test1", "test2" };
}

以及如何使用它:

var settings = (Settings)GetSettings("Settings"); // name of class, from above
settings.Setting1 = Settings.setting1 + 1;        // change some settings
settings.Setting4 = DateTime.Now;
SaveSettings(settings);                   // save all properties of the class to file	

设置类型

如前所述,这将读取类的属性并应用它们。到目前为止,它已经实现了以下类型:stringbooleanintdoubleDatetime字符串列表(List<string>)。
对于其他类型,代码会给出异常,但代码很容易扩展。

存储位置

当前代码将使用本地应用程序文件夹,它将在其中创建一个具有执行(您的)应用程序名称的文件夹。

错误处理

这个例子有基本的错误处理。如果需要,可以添加额外的错误处理。

保存类

public void SaveSettings(object settings, string filename = "settings.config")
{
    // create storage folder and file name
    string storageFolder = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        Path.GetFileNameWithoutExtension(Application.ExecutablePath));
    if (!Directory.Exists(storageFolder))
        Directory.CreateDirectory(storageFolder);
    if (!Directory.Exists(storageFolder))
        throw new Exception($"Could not create folder {storageFolder}");
    string settingsFileName = Path.Combine(storageFolder, filename);
    
    // create file and process class, save properties one by one
    XmlWriterSettings xmlWriterSettings = new XmlWriterSettings()
    {
        Indent = true,
    };
    XmlWriter writer = XmlWriter.Create(settingsFileName, xmlWriterSettings);
    using (writer)
    {
        writer.WriteStartElement("settings");
        var classType = settings.GetType();
        var props = classType.GetProperties();
        for (int i = 0; i < props.Length; i++)
        {
            string fileSetting = char.ToLower(props[i].Name[0]) + props[i].Name.Substring(1);
            
            if (props[i].PropertyType == typeof(string))
            {
                var sett = classType.GetProperty(props[i].Name).GetValue(settings);
                if (sett != null)
                {
                    string s = sett.ToString();
                    if (!string.IsNullOrEmpty(s))
                        writer.WriteElementString(fileSetting, s);
                }
            }
            else if (props[i].PropertyType == typeof(int))
            {
                writer.WriteElementString(fileSetting, 
                classType.GetProperty(props[i].Name).GetValue(settings).ToString());
            }
            else if (props[i].PropertyType == typeof(double))
            {
                writer.WriteElementString(fileSetting, 
                classType.GetProperty(props[i].Name).GetValue(settings).ToString());
            }
            else if (props[i].PropertyType == typeof(DateTime))
            {
                var dt = (DateTime)(classType.GetProperty(props[i].Name).GetValue(settings));
                writer.WriteElementString(fileSetting, dt.ToOADate().ToString());
            }
            else if (props[i].PropertyType == typeof(bool))
            {
                writer.WriteElementString(fileSetting,
                classType.GetProperty(props[i].Name).GetValue(settings).ToString());
            }
            else if (props[i].PropertyType == typeof(List<string>))
            {
                List<string> values =
                classType.GetProperty(props[i].Name).GetValue(settings) as List<string>;
                string val = string.Join(",", values.ToArray());
                writer.WriteElementString(fileSetting, val);
            }
            else
                throw new Exception($"Unknown setting type found: {props[0].PropertyType}");
        }
        
        writer.WriteEndElement();
        writer.Flush();
    }
}

加载一个类

这是读取文件并将属性应用到类并返回它的代码。
请注意,某些部分会引发异常,但可以更改为简单地返回默认设置。
另请注意,该类返回一个对象,因为不可能返回实际的类。因此,需要对类使用的结果进行类型转换。

例子:

var mySettings = (MySettingsClass)GetSettings("MySettingsClass"); // here, the class
                                               // is used is named MySettingsClass

public object GetSettings(string settingsClassName, string filename = "settings.config")
{
// get class type and create default class
    var settingsType = (from assembly in AppDomain.CurrentDomain.GetAssemblies()
                        from t in assembly.GetTypes()
                        where t.Name == settingsClassName
                        select t).FirstOrDefault();
    object settings = Activator.CreateInstance(settingsType);
    
// create storage folder and file name
    string storageFolder = Path.Combine(
        Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
        Path.GetFileNameWithoutExtension(Application.ExecutablePath));
    if (!Directory.Exists(storageFolder))
        Directory.CreateDirectory(storageFolder);
    if (!Directory.Exists(storageFolder))
        throw new Exception($"Could not create folder {storageFolder}");
    string settingsFileName = Path.Combine(storageFolder, filename);
    
// recreate file if missing and return default settings
    if (!File.Exists(settingsFileName))
    {
        SaveSettings(settings);
        return settings;
    }
    
// read and process file
    XmlDocument settingsFile = new XmlDocument();
    try
    {
        settingsFile.Load(settingsFileName);
    }
    catch (Exception ex)
    {
        throw ex;
        // option to return default data
        SaveSettings(settings);
        return settings;
    }
    XmlNode settingsNode = null;
    int n = 0;
    while (n < settingsFile.ChildNodes.Count && settingsNode == null)
    {
        if (settingsFile.ChildNodes[n].Name.ToLower() == "settings")
            settingsNode = settingsFile.ChildNodes[n];
        n++;
    }
    if (settingsNode == null)
    {
        throw new Exception($"Settings section is not found 
                            in settings file {settingsFileName}");
        // option to return default data
        return settings;
    }
    var classType = settings.GetType();
    var props = classType.GetProperties();
    foreach (XmlNode setting in settingsNode.ChildNodes)
    {
        if (setting.ParentNode.Name.ToLower() != "settings")
            break;
        if (setting.NodeType != XmlNodeType.Element)
            continue;
            
        var settingName = props.Where
        (w => string.Compare(w.Name, setting.Name, true) == 0).ToList();
        if (settingName.Count == 0)
            continue;
        if (string.IsNullOrEmpty(settingName[0].Name))
            continue;
            
        // parse setting as type defines
        if (settingName[0].PropertyType == typeof(string))
            classType.GetProperty(settingName[0].Name).SetValue(settings, setting.InnerText);
        else if (settingName[0].PropertyType == typeof(int))
        {
            int val = 0;
            if (int.TryParse(setting.InnerText, out val))
                classType.GetProperty(settingName[0].Name).SetValue(settings, val);
        }
        else if (settingName[0].PropertyType == typeof(double))
        {
            double val = 0;
            if (double.TryParse(setting.InnerText, out val))
                classType.GetProperty(settingName[0].Name).SetValue(settings, val);
        }
        else if (settingName[0].PropertyType == typeof(DateTime))
        {
            double val = 0;
            if (double.TryParse(setting.InnerText, out val))                        
                classType.GetProperty(settingName[0].Name).SetValue
                (settings, DateTime.FromOADate(val));
        }
        else if (settingName[0].PropertyType == typeof(bool))
        {
            bool val = (string.Compare("true", 
            setting.InnerText, true) == 0) || setting.InnerText == "1";
            classType.GetProperty(settingName[0].Name).SetValue(settings, val);
        }
        else if (settingName[0].PropertyType == typeof(List<string>))
        {
            string val = setting.InnerText.Trim();
            if (string.IsNullOrEmpty(val))
            {
                classType.GetProperty(settingName[0].Name).SetValue
                (settings, new List<string>());
                continue;
            }
            List<string> values = val.Split(',').ToList();
            classType.GetProperty(settingName[0].Name).SetValue(settings, values);
        }
        else
            throw new Exception
            ($"Unknown setting type found: {settingName[0].PropertyType}");
    }
    return settings;
}

结论

这只是使用类作为参数并处理类的属性的简单方法。它具有最常见的类型,但可以轻松扩展。此外,文件名和位置也很容易更改。

https://www.codeproject.com/Tips/5325914/Easy-Loading-and-Saving-of-Settings-Stored-as-a-Si

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值