38 lines
1.6 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|