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; } } } |