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-->) Expression.Return(returnTarget, Expression.New(ctr, Expression.Call(_TransitionFunc.MakeGenericMethod(elementType), element))) )), Expression.Label(returnTarget, Expression.Constant(null, type)) ); } private static Func TransitionFunc(T t) { return () => t; } } }