1. 程式人生 > 程式設計 >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# 儲存資料到本地的資料請關注我們其它相關文章!