zoukankan      html  css  js  c++  java
  • ObjectsTypesBytesHelper

    
    namespace Microshaoft
    {
        using System;
        using System.Linq;
        using System.Reflection;
        using System.Collections.Generic;
        using System.Collections.Concurrent;
        using System.Linq.Expressions;
        public static class ObjectsTypesBytesHelper
        {
            public static byte[] ObjectToBytes<T>
                                     (
                                        T Object
                                        , Func
                                            <
                                                int
                                                , int
                                                , MemberInfo
                                                , Type                                    //Member Data Type
                                                , MemberSequenceBytesLengthAttribute
                                                , DynamicPropertyOrFieldAccessor
                                                , byte[]                                // return
                                            > processObjectMemberBytesBlockFunc
                                     )
            {
                Type type = typeof(T);
                Tuple
                    <
                        Type
                        , ClassOrStructBytesLengthAttribute
                        , List
                            <
                                Tuple
                                    <
                                        Type
                                        , ClassOrStructBytesLengthAttribute
                                        , MemberInfo
                                        , Type
                                        , MemberSequenceBytesLengthAttribute
                                        , DynamicPropertyOrFieldAccessor
                                    >
                            >
                    > entry = ObjectsTypesCache.GetOrAdd(type);
                int p = 0;
                List<byte[]> buffersList = new List<byte[]>();
                int i = 1;
                entry.Item3.ForEach
                                (
                                    (x) =>
                                    {
                                        byte[] buffer = processObjectMemberBytesBlockFunc
                                                            (
                                                                i
                                                                , p                    //累计长度
                                                                , x.Item3
                                                                , x.Item4
                                                                , x.Item5
                                                                , x.Item6
                                                            );
                                        p += buffer.Length;
                                        buffersList.Add(buffer);
                                    }
                                );
                ClassOrStructBytesLengthAttribute attribute = entry.Item2;
                int offset = attribute.BytesLength;
                byte[] buff = new byte[offset];
                byte[] buf = BitConverter.GetBytes(p);
                int count = (buf.Length < buff.Length ? buf.Length : buff.Length);
                Buffer.BlockCopy
                            (
                                buf
                                , 0
                                , buff
                                , 0
                                , count
                            );
                Array.Reverse(buff);
                byte[] bytes = new byte[p + offset];
                p = 0;
                Buffer.BlockCopy
                            (
                                buff
                                , 0
                                , bytes
                                , 0
                                , buff.Length
                            );
                p += buff.Length;
                buffersList.ForEach
                                (
                                    (x) =>
                                    {
                                        Buffer.BlockCopy
                                                    (
                                                        x
                                                        , 0
                                                        , bytes
                                                        , p
                                                        , x.Length
                                                    );
                                        p += x.Length;
                                    }
                                );
                return bytes;
            }
        }
        public static class ObjectsTypesCache
        {
            public static ConcurrentDictionary
                                        <
                                            Type
                                            , Tuple
                                                <
                                                    Type            //类的类型
                                                    , ClassOrStructBytesLengthAttribute
                                                    , List
                                                        <
                                                            Tuple
                                                                <
                                                                    Type                                    //类的类型
                                                                    , ClassOrStructBytesLengthAttribute
                                                                    , MemberInfo
                                                                    , Type                                    //Member Data Type
                                                                    , MemberSequenceBytesLengthAttribute
                                                                    , DynamicPropertyOrFieldAccessor
                                                                >
                                                        >
                                                >
                                        > TypesMembersInfosAccessorsDictionaryCache
            {
                get;
                private set;
            }
            static ObjectsTypesCache()
            {
                TypesMembersInfosAccessorsDictionaryCache = new ConcurrentDictionary
                                                                            <
                                                                                Type
                                                                                , Tuple
                                                                                    <
                                                                                        Type
                                                                                        , ClassOrStructBytesLengthAttribute
                                                                                        , List
                                                                                            <
                                                                                                Tuple
                                                                                                    <
                                                                                                        Type
                                                                                                        , ClassOrStructBytesLengthAttribute
                                                                                                        , MemberInfo
                                                                                                        , Type
                                                                                                        , MemberSequenceBytesLengthAttribute
                                                                                                        , DynamicPropertyOrFieldAccessor
                                                                                                    >
                                                                                            >
                                                                                    >
                                                                            >();
            }
            public static Tuple
                            <
                                Type
                                , ClassOrStructBytesLengthAttribute
                                , List
                                    <
                                        Tuple
                                            <
                                                Type
                                                , ClassOrStructBytesLengthAttribute
                                                , MemberInfo
                                                , Type
                                                , MemberSequenceBytesLengthAttribute
                                                , DynamicPropertyOrFieldAccessor
                                            >
                                    >
                            > GetOrAdd(Type type)
            {
                return TypesMembersInfosAccessorsDictionaryCache.GetOrAdd
                                                                    (
                                                                        type
                                                                        , (t) =>
                                                                        {
                                                                            ClassOrStructBytesLengthAttribute typeAttribute =
                                                                                                        (
                                                                                                            (ClassOrStructBytesLengthAttribute[])
                                                                                                            t.GetCustomAttributes
                                                                                                                    (
                                                                                                                        typeof(ClassOrStructBytesLengthAttribute)
                                                                                                                        , false
                                                                                                                    )
                                                                                                        ).OrderBy
                                                                                                            (
                                                                                                                (x) =>
                                                                                                                {
                                                                                                                    return x.AttributeSequence;
                                                                                                                }
                                                                                                            ).ToList().First();
                                                                            Tuple
                                                                                <
                                                                                    Type            //类的类型
                                                                                    , ClassOrStructBytesLengthAttribute
                                                                                    , List
                                                                                        <
                                                                                            Tuple
                                                                                                <
                                                                                                    Type                                        //类的类型
                                                                                                    , ClassOrStructBytesLengthAttribute
                                                                                                    , MemberInfo
                                                                                                    , Type                                        //Member Data Type
                                                                                                    , MemberSequenceBytesLengthAttribute
                                                                                                    , DynamicPropertyOrFieldAccessor
                                                                                                >
                                                                                        >
                                                                                > entry =
                                                                                        new Tuple
                                                                                                <
                                                                                                    Type
                                                                                                    , ClassOrStructBytesLengthAttribute
                                                                                                    , List
                                                                                                        <
                                                                                                            Tuple
                                                                                                                <
                                                                                                                    Type
                                                                                                                    , ClassOrStructBytesLengthAttribute
                                                                                                                    , MemberInfo
                                                                                                                    , Type
                                                                                                                    , MemberSequenceBytesLengthAttribute
                                                                                                                    , DynamicPropertyOrFieldAccessor
                                                                                                                >
                                                                                                        >
                                                                                                >
                                                                                                (
                                                                                                    type
                                                                                                    , typeAttribute
                                                                                                    , GetTypeAllMembersInfosList(type, typeAttribute)
                                                                                                );
                                                                            return entry;
                                                                        }
                                                                    );
            }
            private static List
                            <
                                Tuple
                                    <
                                        Type                                        //类的类型
                                        , ClassOrStructBytesLengthAttribute
                                        , MemberInfo
                                        , Type                                        //Member Data Type
                                        , MemberSequenceBytesLengthAttribute
                                        , DynamicPropertyOrFieldAccessor
                                    >
                            > GetTypeAllMembersInfosList(Type t, ClassOrStructBytesLengthAttribute typeAttribute)
            {
                List
                    <
                        Tuple
                            <
                                Type                                                //类的类型
                                , ClassOrStructBytesLengthAttribute
                                , MemberInfo
                                , Type                                                //Member Data Type
                                , MemberSequenceBytesLengthAttribute
                                , DynamicPropertyOrFieldAccessor
                            >
                    > list = null;
                t.GetMembers().ToList().Where
                                                (
                                                    (mi) =>
                                                    {
                                                        var r = false;
                                                        if (mi.MemberType == MemberTypes.Field || mi.MemberType == MemberTypes.Property)
                                                        {
                                                            var attributes =
                                                                            (
                                                                                (MemberSequenceBytesLengthAttribute[])mi.GetCustomAttributes
                                                                                                        (
                                                                                                            typeof(MemberSequenceBytesLengthAttribute)
                                                                                                            , false
                                                                                                        )
                                                                             ).OrderBy
                                                                                                            (
                                                                                                                (x) =>
                                                                                                                {
                                                                                                                    return x.AttributeSequence;
                                                                                                                }
                                                                                                            ).ToList();
                                                            if (attributes.Count > 0)
                                                            {
                                                                var attribute = attributes.First();
                                                                if (list == null)
                                                                {
                                                                    list = new List
                                                                                    <
                                                                                        Tuple
                                                                                            <
                                                                                                Type                                    //类的类型
                                                                                                , ClassOrStructBytesLengthAttribute
                                                                                                , MemberInfo
                                                                                                , Type                                    //Member Data Type
                                                                                                , MemberSequenceBytesLengthAttribute
                                                                                                , DynamicPropertyOrFieldAccessor
                                                                                            >
                                                                                    >();
                                                                }
                                                                Type type = null;
                                                                if (mi.MemberType == MemberTypes.Field)
                                                                {
                                                                    type = ((FieldInfo)mi).FieldType;
                                                                }
                                                                else if (mi.MemberType == MemberTypes.Property)
                                                                {
                                                                    type = ((PropertyInfo)mi).PropertyType;
                                                                }
                                                                Tuple
                                                                    <
                                                                         Type
                                                                        , ClassOrStructBytesLengthAttribute
                                                                        , MemberInfo
                                                                        , Type                                                    //Member Data Type
                                                                        , MemberSequenceBytesLengthAttribute
                                                                        , DynamicPropertyOrFieldAccessor
                                                                     > entry = new Tuple
                                                                                    <
                                                                                        Type                                    //类的类型
                                                                                        , ClassOrStructBytesLengthAttribute
                                                                                        , MemberInfo
                                                                                        , Type                                    //Member Data Type
                                                                                        , MemberSequenceBytesLengthAttribute
                                                                                        , DynamicPropertyOrFieldAccessor
                                                                                    >
                                                                                    (
                                                                                        t
                                                                                        , typeAttribute
                                                                                        , mi
                                                                                        , type
                                                                                        , attribute
                                                                                        , new DynamicPropertyOrFieldAccessor(mi)
                                                                                     );
                                                                list.Add(entry);
                                                                r = true;
                                                            }
                                                        }
                                                        return r;
                                                    }
                                                ).ToList();
                var result = list.OrderBy
                                    (
                                        (entry) =>
                                        {
                                            return entry.Item5.AttributeSequence;
                                        }
                                    ).ToList();
                return result;
            }
        }
        public class DynamicPropertyOrFieldAccessor
        {
            private Func<object, object> m_getter;
            //public DynamicPropertyAccessor(Type type, string propertyName)
            //    : this(type.GetProperty(propertyName))
            //{
            //}
            public DynamicPropertyOrFieldAccessor(MemberInfo memberInfo)
            {
                // target: (object)((({TargetType})instance).{Property})
                // preparing parameter, object type
                ParameterExpression instance = Expression.Parameter
                                                                (
                                                                    typeof(object),
                                                                    "instance"
                                                                );
                // ({TargetType})instance
                Expression instanceCast = Expression.Convert
                                                        (
                                                            instance
                                                            , memberInfo.ReflectedType
                                                        );
                // (({TargetType})instance).{Property}
                Expression memberAccess = Expression.PropertyOrField
                                                            (
                                                                instanceCast
                                                                , memberInfo.Name
                                                            );
                // (object)((({TargetType})instance).{Property})
                UnaryExpression castPropertyValue = Expression.Convert
                                                                    (
                                                                        memberAccess
                                                                        , typeof(object)
                                                                    );
                // Lambda expression
                Expression<Func<object, object>> lambda = Expression.Lambda<Func<object, object>>
                                                                                        (
                                                                                            castPropertyValue, instance
                                                                                        );
                this.m_getter = lambda.Compile();
            }
            public object GetValue(object o)
            {
                return this.m_getter(o);
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Linq;
        using System.Reflection;
        using System.Collections.Generic;
        using System.Collections.Concurrent;
        [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, AllowMultiple = true)]
        public class ClassOrStructBytesLengthAttribute : Attribute
        {
            public int BytesLength
            {
                get;
                set;
            }
            public int AttributeSequence
            {
                get;
                set;
            }
        }
        [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)]
        public class MemberSequenceBytesLengthAttribute : Attribute
        {
            public int MemberSequence
            {
                get;
                set;
            }
            public int AttributeSequence
            {
                get;
                set;
            }
            public int BytesLength
            {
                get;
                set;
            }
        }
    }
    
    
  • 相关阅读:
    LoginStatus 如何指向不同的登陆地址以及“invalid FORMATETC”
    不排序和可以重复Key的SortedList。
    一个新样式
    如何给另一个桌面的程序发送消息?
    Html使用自定义光标的一点需要注意的小问题。
    用stream.Read不能完整读取内容的问题。
    全国天气预报代码(转帖)
    Access处理DISTINCT的Bug?
    asp.net和asp运行结果不同?
    学习枚举类型/FlagsAttribute属性
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2452991.html
Copyright © 2011-2022 走看看