.net 解析以竖线,美元符等分割符分割的字符串为实体

时间:2020-05-20
本文章向大家介绍.net 解析以竖线,美元符等分割符分割的字符串为实体,主要包括.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);

原文地址:https://www.cnblogs.com/hankuikui/p/12923495.html