v9.8.2018.0605   由DataReader直接映射实体列表,以支持netstandard的MySql和SQLite,且提升性能
大石头 authored at 2018-06-05 00:45:23
2.48 KiB
X
using System;
using System.Collections;
using System.Collections.Generic;
using NewLife.Reflection;

namespace NewLife.Serialization
{
    /// <summary>列表数据编码</summary>
    public class BinaryList : BinaryHandlerBase
    {
        /// <summary>初始化</summary>
        public BinaryList()
        {
            // 优先级
            Priority = 20;
        }

        /// <summary>写入</summary>
        /// <param name="value"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public override Boolean Write(Object value, Type type)
        {
            if (!type.As<IList>()) return false;

            var list = value as IList;
            // 先写入长度
            if (list == null || list.Count == 0)
            {
                Host.WriteSize(0);
                return true;
            }

            Host.WriteSize(list.Count);

            // 循环写入数据
            foreach (var item in list)
            {
                Host.Write(item);
            }

            return true;
        }

        /// <summary>读取</summary>
        /// <param name="type"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override Boolean TryRead(Type type, ref Object value)
        {
            if (!type.As<IList>()) return false;

            // 先读取长度
            var count = Host.ReadSize();
            if (count == 0) return true;

            if (value == null && type != null)
            {
                // 数组的创建比较特别
                if (type.As<Array>())
                    value = Array.CreateInstance(type.GetElementTypeEx(), count);
                else
                    value = type.CreateInstance();
            }

            // 子元素类型
            var elmType = type.GetElementTypeEx();

            var list = value as IList;
            // 如果是数组,则需要先加起来,再
            //if (value is Array) list = typeof(IList<>).MakeGenericType(value.GetType().GetElementTypeEx()).CreateInstance() as IList;
            for (var i = 0; i < count; i++)
            {
                Object obj = null;
                if (!Host.TryRead(elmType, ref obj)) return false;

                if (value is Array)
                    list[i] = obj;
                else
                    list.Add(obj);
            }

            return true;
        }
    }
}