Reflection + custom properties save data to local

Time:2021-9-22

Recently, I encountered the need to save data in the process of the project. I want to save part of the data of the entity class. I plan to use the reflection + user-defined feature to save the data, which is conducive to expansion
1. The reflection implementation can flexibly obtain the data to be saved. Since only part of the data of the entity class (model) needs to be saved, the data to be saved is marked with user-defined features. At the same time, the data is required to be saved in. CSV format. Adding user-defined features is conducive to the description of the header
2. Implement custom features

public class ResultAttribute : Attribute
    {
        private bool _IsSave;
        /// 
        ///Save
        /// 
        public bool IsSave
        {
            get { return _IsSave; }
            set { _IsSave = value; }
        }

        private string _SaveName;
        /// 
        ///The name of the first line of the. CSV file
        /// 
        public string SaveName
        {
            get { return _SaveName; }
            set { _SaveName = value; }
        }
    }
  1. Add a custom label to the model class
    After adding a custom tag, the attribute and. CSV header name to be saved can be identified during the reflection process
public class TestResultModel:ViewModelBase
    {

        private int _TestNumber;
        /// 
        ///Serial number
        /// 
        [equationresult (savename = "sequence number", issave = true)]
        public int TestNumber
        {
            get { return _TestNumber; }
            set { _TestNumber = value; RaisePropertyChanged(); }
        }

        private string _TestResult;
        /// 
        ///Test results
        /// 
        [equationresult (savename = "test result", issave = true)]
        public string TestResult
        {
            get { return _TestResult; }
            set { _TestResult = value; RaisePropertyChanged(); }
        }

        private DateTime _TestTime;
        /// 
        ///Test time
        /// 
        [equationresult (savename = "test time", issave = true)]
        public DateTime TestTime
        {
            get { return _TestTime; }
            set { _TestTime = value; RaisePropertyChanged(); }
        }
						
        private string _MeterSn;
        /// 
        ///Instrument Sn number
        /// 
        public string MeterSn
        {
            get { return _MeterSn; }
            set { _MeterSn = value; RaisePropertyChanged(); }
        }
   }
  1. Save data using reflection
/// 
        ///Get data to save
        /// 
        /// 
        /// 
        ///Is it the header of the first row
        /// 
        private string GetSaveStr(T tClass, bool IsHead = false) where T : class
        {
            StringBuilder sb = new StringBuilder();
            //MSDN: the getproperties method does not return properties in a specific order, such as alphabetical or declaration order. Your code cannot rely on the return order of properties because the order will be different. 
            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
                    {
                        ;// No code
                    }
                }
            }
            return sb.ToString();
        }



        /// 
        ///Save test information
        /// 
        /// 
        public void SaveTestDataToCsv(List 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);            // Set the start position of the flow to start
                    string data = GetSaveStr(listModel[0], true);       // Write first line
                    sw.WriteLine(data);  // Write data stream
                    sw.Flush();
                    for (int i = 0; i < listModel.Count; i++)
                    {
                        sw.BaseStream.Seek(0, SeekOrigin.End);
                        data = GetSaveStr(listModel[i]);
                        sw.WriteLine(data);  // Write data stream
                        sw.Flush();
                    }
                }
            }
        }
  1. When using reflection to obtain the attribute list, the order of the list may be inconsistent. You can add a sorting feature to the custom feature, set the sorting value for each attribute, obtain the sorting feature at the same time after obtaining the attribute list by reflection, and sort the attribute list according to the sorting feature to ensure that the order of each attribute list is consistent