.net 解析以豎線,美元符等分割符分割的字符串為實體


一.需求:

交易返回的一大長串字符串:分項之間使用分割符‘|’分割。部分數據可能為空,如"xx||xx",即每一數據項的位置是固定的。

如果數據為多條,記錄之間以‘$’分割。

例如:’xx|20200203|aaa1|$xx|20200104|aaa2|’.

二.分析 :

1. 多條記錄,首先就要進行分隔成一個數組,然后再對數組中的數據進行處理。

2.使用split方法對一條數據進行分隔為一個數據,那索引位置就對應着一個數據項。

3.在建立的實體的屬性上,添加一個定義的attribute來記錄這個數據項對應的索引,如LocationAttribute。

4.通過反射獲取對實體的所有屬性,遍歷屬性集合,獲取屬性上的索引,即可得到這個數據實際的值。

5.再通過反射創建實體的實例,給實體的屬性賦值。即可。

 

實現代碼:

namespace Cis.Hus.Service.Utils
{
    /// <summary>/// </summary>
    public class StringUtils
    {
        /// <summary>
        /// 解析單個字符串為對象T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static T ParseOne<T>(string source)
        {
            string[] split = source.Split('|');

            var accessor = new DynamicAccessor<T>();
            T t = Activator.CreateInstance<T>();

            var props = typeof(T).GetProperties();

            foreach (var prop in props)
            {
                var p = prop.GetCustomAttributes(true).OfType<LocationAttribute>().FirstOrDefault();
                if (p != null)
                {
                    if (p.Column < split.Length)
                    {
                        var value = split[p.Column - 1];
                        var newValue = ChangeValueType(value, prop.PropertyType);
                        accessor.SetValue(t, prop.Name, newValue);
                    }
                }
            }

            return t;
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="value">要轉換的值</param>
        /// <param name="conversionType">要轉換成的類型</param>
        /// <returns></returns>
        private static object ChangeValueType(object value, Type conversionType)
        {
            if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
            {
                if (value != null)
                {
                    NullableConverter nullableConverter = new NullableConverter(conversionType);
                    conversionType = nullableConverter.UnderlyingType;
                }
                else
                {
                    return null;
                }
            }
            return Convert.ChangeType(value, conversionType);

        }
        /// <summary>
        /// 將字符串數組解析為對象數組
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List<T> Parse<T>(string[] source)
        {
            List<T> result = new List<T>();
            var type = typeof(T).GetType();
            //反射訪問器  
            //TODO 測試一下,DynamicAccessor和 PropertyAccessor的性能差異
            var accessor = new DynamicAccessor<T>();

            for (int i = 0; i < source.Length; i++)
            {
                var one = ParseOne<T>(source[i]);
                result.Add(one);
            }

            return result;
        }

        /// <summary>
        /// 將字符串解析為對象數組
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List<T> Parse<T>(string source)
        {

            //如果業務數據為多條記錄,記錄之間以‘$’分割
            if (source.Contains("$"))
            {
                string[] items = source.Split('$');
                return Parse<T>(items);
            }

            var obj = ParseOne<T>(source);
            return new List<T> { obj };
        }


    }
}

 

/// <summary>
    /// 插入定位attribute
    /// </summary>
    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Class, AllowMultiple = false)]
    public class LocationAttribute : Attribute
    {
        #region Fields

        /// <summary>
        /// 列索引
        /// </summary>
        public int Column { get; set; }
        

        #endregion

    }

 

調用:

List<User> data = StringUtils.Parse<User>(data);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM