2023-11-21 23:05:03 +08:00

38 lines
1.6 KiB
C#

using System;
using System.Linq.Expressions;
using System.Reflection;
namespace CPF.Windows.Json.Deserialize
{
[ExpressionBuildType(DeserializeBuildTypeEnum.Lazy)]
internal class LazyBuild : ExpressionJsonResolve
{
#region pregenerated metas
static MethodInfo _TransitionFunc = typeof(LazyBuild).GetMethod(nameof(TransitionFunc), BindingFlags.Static | BindingFlags.NonPublic);
#endregion
internal static BlockExpression Build(Type type)
{
LabelTarget returnTarget = Expression.Label(type, "returnLable");
Type elementType = type.GetGenericArguments()[0];
ParameterExpression element = Expression.Variable(elementType, "element");
var ctr = type.GetAppointTypeCtor(typeof(Func<>).MakeGenericType(elementType));
return Expression.Block(new[] { element },
Expression.IfThenElse(
Expression.Call(ExpressionMembers.Reader, JsonReader._ReadBoolNull),
Expression.Return(returnTarget, Expression.Constant(null, type)),
Expression.Block(
Expression.Assign(element, ExpressionMembers.GetMethodCall(elementType)), //inject = Read<T>(); T-->)
Expression.Return(returnTarget, Expression.New(ctr, Expression.Call(_TransitionFunc.MakeGenericMethod(elementType), element)))
)),
Expression.Label(returnTarget, Expression.Constant(null, type))
);
}
private static Func<T> TransitionFunc<T>(T t)
{
return () => t;
}
}
}