最近在專案程序中遇到了保存資料的需求,對物體類的部分資料進行保存,打算采用反射+自定義特性來實作資料保存,利于擴展
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; }
}
}
- 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(); }
}
}
- 使用反射進行資料保存
/// <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 = https://www.cnblogs.com/ndtlyych/archive/2020/12/15/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();
}
}
}
}
- 使用反射獲取屬性串列時,串列的順序可能會不一致,可以在自定義特性中加入排序特性,對每個屬性設定排序值,反射獲取屬性串列后同時獲取排序特性,根據排序特性對屬性串列進行排序保證每次屬性串列的順序一致
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/235159.html
標籤:.NET技术
