C#将类属性保存到Ini文件方法(利用拓展方法,反射方式获取到分组名和属性名称属性值)

前言:最近学习C#高级课程,里面学到了利用反射和可以得到属性的特性、属性名、属性值,还有拓展方法,一直想将学到的东西利用起来,刚好今天在研究PropertyGrid控件时,想方便一点保存属性值到配置文件,当然同理也可以保存对象的属性值到Xml文件 ,类似Json文件有JSON序列化保存更快,但是其中用到了反射技术,在属性多的情况下,性能会低一点. 后面有时间添加读取反序列化的.

IniHelper类代码如下,提供了读写方法接口

cs 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace Files
{
    public class IniHelper
    {
        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string section, string key, string def, StringBuilder retVal, int size, string filePath);

        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        /// <summary>
        /// 泛型读取
        /// </summary>
        /// <typeparam name="T">值类型</typeparam>
        /// <param name="section">部分</param>
        /// <param name="key">键名</param>
        /// <param name="filePath">路径</param>
        /// <param name="Default">默认值</param>
        /// <returns></returns>
        public static T Read<T>(string section, string key, string filePath,T Default = default(T))
        {
            StringBuilder temp = new StringBuilder(255);
            GetPrivateProfileString(section, key,"", temp, 255, filePath);
            try
            {
                string[] str = temp.ToString().Split('%');
                if(str[0] != "")
                {
                    return (T)(TypeDescriptor.GetConverter(typeof(T))).ConvertFromInvariantString(str[0]);
                }
                else
                {
                    return (T)Default;
                }
            }
            catch (Exception err)
            {
                return (T)Default;
            }
            
        }

        /// <summary>
        /// 普通读取
        /// </summary>
        /// <param name="section">部分</param>
        /// <param name="key">键名</param>
        /// <param name="filePath">路径</param>
        /// <param name="Default">默认值</param>
        /// <returns></returns>
        public static string Read(string section, string key, string filePath,string Default)
        {
            StringBuilder temp = new StringBuilder(255);
            GetPrivateProfileString(section, key, "", temp, 255, filePath);
            string[] s = temp.ToString().Split(new char[] { '%' });
            if (s[0] != "")
            {
                return s[0].ToString();
            }
            else
            {
                
                return Default;
            }
        }

        /// <summary>
        /// 写入值
        /// </summary>
        /// <param name="section">部分</param>
        /// <param name="key">键名</param>
        /// <param name="value">值</param>
        /// <param name="filePath">路径</param>
        public static void Write(string section, string key, string value, string filePath)
        {
            if(WritePrivateProfileString(section, key, value, filePath) <= 0)
            {
                WritePrivateProfileString(section, key, value, filePath);
            }
        }

        /// <summary>
        /// Ini保存类属性分组,属性名,属性值到Ini文件
        /// </summary>
        /// <typeparam name="T">泛型对象</typeparam>
        /// <param name="t">具体泛型对象</param>
        /// <param name="filePath">文件完整路径</param>
        public static void SaveObj<T>(T t, string filePath,string DefaultSection = "Default") where T:class
        {
            Type type = t.GetType();
            foreach (var item in type.GetProperties())
            {
                string Section = item.PropertyGetCategoryAttribute() ?? DefaultSection;
                string Key = item.Name.ToString();
                string Value = item.GetValue(t).ToString();
                Write(Section, Key, Value, filePath);
            }
        }

        
    }
}

下面是拓展方法的代码如下

cs 复制代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;


/// <summary>
    /// 属性拓展类
    /// </summary>
    public static class PropertyExpand
    {
        /// <summary>
        /// 通过属性 返回 其特性分组名
        /// </summary>
        /// <param name="propertyInfo">属性类型约束</param>
        /// <returns></returns>
        public static string PropertyGetCategoryAttribute(this PropertyInfo propertyInfo)
        {
            var section = propertyInfo.GetCustomAttributes(typeof(CategoryAttribute), false);
            return section.Length > 0 ? ((CategoryAttribute)section[0]).Category : null;
        }
    }

相当于一个实操笔记,共勉!!!

相关推荐
现在,此刻6 分钟前
leetcode 11. 盛最多水的容器 -java
java·算法·leetcode
DKPT34 分钟前
Java设计模式之开闭原则介绍与说明
java·设计模式·开闭原则
hyy27952276841 小时前
企业级WEB应用服务器TOMCAT
java·前端·tomcat
布朗克1681 小时前
Spring Boot项目通过Feign调用三方接口的详细教程
java·spring boot·feign
Arva .1 小时前
Spring基于XML的自动装配
xml·java·spring
Hemy081 小时前
QT_QUICK_BACKEND 环境变量详解(AI生成)
开发语言·qt
艾莉丝努力练剑2 小时前
深入详解C语言的循环结构:while循环、do-while循环、for循环,结合实例,讲透C语言的循环结构
c语言·开发语言·c++·学习
ts码农3 小时前
Aspose使用
c#·aspose
晨非辰3 小时前
#C语言——学习攻略:自定义类型路线--结构体--结构体类型,结构体变量的创建和初始化,结构体内存对齐,结构体传参,结构体实现位段
c语言·开发语言·经验分享·学习·其他·学习方法·visual studio
帅得不敢出门3 小时前
Android Framework定制长按电源键关机的窗口
android·java·framework