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