c# 反射+自定义特性保存数据至本地

 更新时间:2020年12月17日 08:48:46   作者:ndtlyych  
这篇文章主要介绍了c# 反射+自定义特性保存数据至本地的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下

最近在项目过程中遇到了保存数据的需求,对实体类的部分数据进行保存,打算采用反射+自定义特性来实现数据保存,利于扩展

1. 采用反射实现能够灵活获取要保存的数据,由于只需要保存实体类(Model)的部分数据,因此采用自定义特性标记需要保存的数据,同时数据要求以.csv格式保存,添加自定义特性有利于对表头进行描述

2. 实现自定义特性

  public class ResultAttribute : Attribute
  {
    private bool _IsSave;
    /// <summary>
    /// 是否保存
    /// </summary>
    public bool IsSave
    {
      get { return _IsSave; }
      set { _IsSave = value; }
    }

    private string _SaveName;
    /// <summary>
    /// .csv文件第一行的名称
    /// </summary>
    public string SaveName
    {
      get { return _SaveName; }
      set { _SaveName = value; }
    }
  }

3.Model类添加自定义标签

添加自定义标签后,反射过程中就能识别要保存的属性和.csv头名称

 public class TestResultModel:ViewModelBase
  {

    private int _TestNumber;
    /// <summary>
    /// 序号
    /// </summary>
    [EquationResult(SaveName = "序号", IsSave = true)]
    public int TestNumber
    {
      get { return _TestNumber; }
      set { _TestNumber = value; RaisePropertyChanged(); }
    }

    private string _TestResult;
    /// <summary>
    /// 测试结果
    /// </summary>
    [EquationResult(SaveName = "测试结果", IsSave = true)]
    public string TestResult
    {
      get { return _TestResult; }
      set { _TestResult = value; RaisePropertyChanged(); }
    }

    private DateTime _TestTime;
    /// <summary>
    /// 测试时间
    /// </summary>
    [EquationResult(SaveName = "测试时间", IsSave = true)]
    public DateTime TestTime
    {
      get { return _TestTime; }
      set { _TestTime = value; RaisePropertyChanged(); }
    }
						
    private string _MeterSn;
    /// <summary>
    /// 仪器SN号
    /// </summary>
    public string MeterSn
    {
      get { return _MeterSn; }
      set { _MeterSn = value; RaisePropertyChanged(); }
    }
  }	

4.使用反射进行数据保存

 /// <summary>
    /// 获得要保存的数据
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="tClass"></param>
    /// <param name="IsHead">是不是第一行的表头</param>
    /// <returns></returns>
    private string GetSaveStr<T>(T tClass, bool IsHead = false) where T : class
    {
      StringBuilder sb = new StringBuilder();
      //msdn:GetProperties方法不按特定顺序(如字母顺序或声明顺序)返回属性。 你的代码不能依赖属性的返回顺序,因为该顺序会有所不同。 
      PropertyInfo[] infoarr = tClass.GetType().GetProperties();     
      foreach (var property in infoarr)
      {
        if (property.GetCustomAttribute(typeof(EquationResultAttribute), false) is EquationResultAttribute bute)
        {
          if (bute.IsSave && IsHead)
          {
            sb.Append(bute.SaveName + ",");
          }
          else if (bute.IsSave && !IsHead)
          {
            sb.Append(property.GetValue(tClass).ToString() + ",");
          }
          else
          {
            ;//无代码
          }
        }
      }
      return sb.ToString();
    }



    /// <summary>
    /// 保存测试信息
    /// </summary>
    /// <param name="listModel"></param>
    public void SaveTestDataToCsv(List<TestDataModel> listModel)
    {
      using (FileStream fs = new FileStream(CsvSavePath, FileMode.OpenOrCreate, FileAccess.Write))
      {
        using (StreamWriter sw = new StreamWriter(fs,Encoding.Default))
        {
          sw.BaseStream.Seek(0, SeekOrigin.Begin);      //设置流的起始位置为开始
          string data = GetSaveStr(listModel[0], true);    //写入第一行
          sw.WriteLine(data); //写入数据流
          sw.Flush();
          for (int i = 0; i < listModel.Count; i++)
          {
            sw.BaseStream.Seek(0, SeekOrigin.End);
            data = GetSaveStr(listModel[i]);
            sw.WriteLine(data); //写入数据流
            sw.Flush();
          }
        }
      }
    }

5.使用反射获取属性列表时,列表的顺序可能会不一致,可以在自定义特性中加入排序特性,对每个属性设置排序值,反射获取属性列表后同时获取排序特性,根据排序特性对属性列表进行排序保证每次属性列表的顺序一致

以上就是c# 反射+自定义特性保存数据至本地的详细内容,更多关于c# 保存数据到本地的资料请关注脚本之家其它相关文章!

相关文章

  • C# winform分页查询的实现示例

    C# winform分页查询的实现示例

    这篇文章主要介绍了C# winform分页查询的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 深入分析C# Task

    深入分析C# Task

    这篇文章主要介绍了C# Task的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习C# Task的相关知识,感兴趣的朋友可以了解下
    2020-08-08
  • C#中的out关键字用法详解

    C#中的out关键字用法详解

    在 C# 中,out 关键字是一个修饰符,它允许你在方法内部创建一个临时的变量,用于接收传递进来的参数值,并在方法执行完毕后,将该变量的值返回给调用方法的对象,本文将给大家详细介绍一下C#中的out关键字用法,需要的朋友可以参考下
    2024-02-02
  • C#打包部署并把.net framework框架打到安装包的方法步骤

    C#打包部署并把.net framework框架打到安装包的方法步骤

    打包c#程序时,有时需要添加.net framework组件到安装包,本文就来介绍一下C#打包部署并把.net framework框架打到安装包的方法步骤,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10
  • 遍历Hashtable 的几种方法

    遍历Hashtable 的几种方法

    遍历Hashtable 的几种方法...
    2007-03-03
  • 基于C#实现端口扫描器(单线程和多线程)

    基于C#实现端口扫描器(单线程和多线程)

    本文主要介绍了基于C#分别通过单线程和多线程实现端口扫描,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Winform实现调用asp.net数据接口实例

    Winform实现调用asp.net数据接口实例

    这篇文章主要介绍了Winform实现调用asp.net数据接口的方法,以实例的形式讲述了数据接口及反射辨别响应的实现方法,具有一定的参考借鉴价值,需要的朋友可以参考下
    2014-10-10
  • 利用C#实现AOP常见的几种方法详解

    利用C#实现AOP常见的几种方法详解

    AOP面向切面编程(Aspect Oriented Programming),是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。下面这篇文章主要给大家介绍了关于利用C#实现AOP常见的几种方法,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09
  • C#实现Word转换RTF的示例代码

    C#实现Word转换RTF的示例代码

    这篇文章主要为大家详细介绍了如何利用C#实现Word转换RTF,文中的示例代码讲解详细,对我们学习C#有一定的帮助,感兴趣的小伙伴可以跟随小编一起了解一下
    2022-12-12
  • Visual Stodio2022中没有mysql.dll的解决办法

    Visual Stodio2022中没有mysql.dll的解决办法

    这篇文章介绍了Visual Stodio2022中没有mysql.dll的解决办法,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12

最新评论