CPF/CPF.Windows/Json/Formatter/Serializer/SerializerObjectJump.cs

58 lines
2.0 KiB
C#
Raw Normal View History

2023-11-21 23:05:03 +08:00
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();
}
}
}