c# 反射+自定义特性保存数据至本地
作者:ndtlyych 发布时间:2023-03-14 03:07:40
标签: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.使用反射获取属性列表时,列表的顺序可能会不一致,可以在自定义特性中加入排序特性,对每个属性设置排序值,反射获取属性列表后同时获取排序特性,根据排序特性对属性列表进行排序保证每次属性列表的顺序一致
来源:https://www.cnblogs.com/ndtlyych/p/14139714.html


猜你喜欢
- 目录或库文件名中包含汉字或空格的话,请将其用半角双引号括住。项目、属性、C/C++、附加包含目录:填写附加头文件所在目录 分号间隔多项项目、
- 本文介绍了Android轻松实现多语言的方法示例,分享给大家,具体如下:1.创建多语言包2.首先在onCreate方法中调用此方法查看上一次
- 一、JMeter后端 * 介绍说到JMeter后端 * ,必须要从源头BackendListener开始说,最后延伸到我们需要的Backen
- 上一篇介绍了elasticsearch的client结构,client只是一个门面,在每个方法后面都有一个action来承接相应的功能。但是
- 先从本地把图片上传到服务器,然后根据URL把头像处理成圆形头像。因为上传图片用到bmob的平台,所以要到bmob(http://www.bm
- 背景工作中遇到业务诉求是通过OpenCV对图片进行一些判断操作和优化,这里是看了部分不错的文章,希望总结一个自己的学习过程,温故而知新,有不
- 日常工作中,不管你是写Unit Test,还是采用TDD的编程方式进行开发,都会遇到断言。而断言的风格常见的会有Assert、BDD风格,对
- 在客户机和服务器之间建立单一的双向连接,这就意味着客户只需要发送一个请求到服务端,那么服务端则会进行处理,处理好后则将其返回给客户端,客户端
- 此处网上最多的做法是需要修改tomcat的参数配置大致如下:<Connector port="8080" prot
- 再做一个项目的时候,要求标题栏的标题再中间,样式,字体大小都要自定义。左边一个返回按钮,一个关闭按钮,右边定义一个提交按钮,有时候显示有时候
- Spring Rest接口路径参数可选我有一个 Spring Rest 服务,其中有一个路径参数是可选的(实际情况是我原来将参数放到路径中,
- eclipse运行tomcat提示端口被占用今天碰到一个问题,在eclipse中运行一个程序,eclipse里面的tomcat一启动就报错说
- 结构体概念在C#中,结构体是值类型,一般适用于表示类似Point、Rectangle、Color的对象值类型能够降低对堆的管理、使用。降低垃
- import java.io.BufferedInputStream;import java.util.ArrayList;import j
- 一、题目描述题目实现:使用网络编程时,需要通过Socket传递对象。二、解题思路创建一个类:Student,实现序列化Student类包含两
- 最近解决了一个令我头疼好久的问题,就是三星手机拍照图片旋转的问题,项目中有上传图片的功能,那么涉及到拍照,从相册中选择图片,别的手机都ok没
- 在我们移动应用开发过程中,偶尔有可能会接到这种需求:1、在手机桌面创建一个窗口,类似于360的悬浮窗口,点击这个窗口可以响应(至于窗口拖动我
- 一、堆的概念堆的定义:n个元素的序列{k1 , k2 , … , kn}称之为堆,当且仅当满足以下条件时:(1)ki
- 一、SpringBoot 指定配置文件路径:在 SpringBoot 中,可以将配置文件放在 jar 包外面,这样可以方便地修改配置而不需要
- Java枚举类型enum的详解及使用最近跟同事讨论问题的时候,突然同事提到我们为什么Java 中定义的常量值不采用enmu 枚举