c# 反射+自定義特性儲存資料至本地
阿新 • • 發佈:2020-12-18
最近在專案過程中遇到了儲存資料的需求,對實體類的部分資料進行儲存,打算採用反射+自定義特性來實現資料儲存,利於擴充套件
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# 儲存資料到本地的資料請關注我們其它相關文章!