58 lines
2.0 KiB
C#
58 lines
2.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Threading;
|
|
|
|
namespace CPF.Windows.Json.Serializer
|
|
{
|
|
internal static class SerializerObjectJump
|
|
{
|
|
private static SpinLock _spinLock = new SpinLock();
|
|
|
|
private static readonly Dictionary<Type, Action<object, JsonSerializerHandler>> JumpActions = new Dictionary<Type, Action<object, JsonSerializerHandler>>();
|
|
|
|
|
|
#if !Net4
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
#endif
|
|
internal static Action<object, JsonSerializerHandler> GetThreadSafetyJumpAction(Type t)
|
|
{
|
|
if (JumpActions.TryGetValue(t, out var ac))
|
|
return ac;
|
|
else
|
|
{
|
|
try
|
|
{
|
|
bool i = false;
|
|
_spinLock.Enter(ref i);
|
|
if (!JumpActions.TryGetValue(t,out ac))
|
|
{
|
|
ac = GenerateAction(t);
|
|
JumpActions.Add(t, ac);
|
|
}
|
|
return ac;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw e;
|
|
}
|
|
finally
|
|
{
|
|
_spinLock.Exit();
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static Action<object, JsonSerializerHandler> GenerateAction( Type t)
|
|
{
|
|
ParameterExpression objArg = Expression.Parameter(typeof(object), "instance");
|
|
Expression originalArg = Expression.Convert(objArg, t);
|
|
ParameterExpression handlerArg = Expression.Parameter(typeof(JsonSerializerHandler), "handler");
|
|
var body = Expression.Call(typeof(FormattingProvider<>).MakeGenericType(t).GetMethod("Convert",BindingFlags.NonPublic|BindingFlags.Static), originalArg, handlerArg);
|
|
return Expression.Lambda<Action<object, JsonSerializerHandler>>(body, objArg, handlerArg).Compile();
|
|
}
|
|
}
|
|
}
|