using EC.Helper.RabbitFunc.Runtime; using System.Collections.ObjectModel; using System.Text; namespace EC.Helper.RabbitFunc.Expressions; public class LambdaExpression : Expression { internal LambdaExpression(string name, Expression body, params ParameterExpression[] parameters) : base(ExpressionType.Lambda) { Name = name; Parameters = new ReadOnlyCollection(parameters); Body = body; } public RabbitDomain Domain { get; internal set; } public string Name { get; } public ReadOnlyCollection Parameters { get; } public Expression Body { get; } public override Type Type => typeof(double); public Delegate Compile(Type deletageType = null) { var lambdaCompiler = new ExpressionCompiler(); return lambdaCompiler.Compile(this, deletageType); } public T Compile() { return (T)(object)Compile(typeof(T)); } public override object Eval(RuntimeContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); var lambdaContext = new RuntimeContext(context); lambdaContext.Domain = Domain; for (int i = 0; i < Parameters.Count; i++) { var parameter = Parameters[i]; var value = parameter.Eval(context); lambdaContext.Variable(parameter.Name, value); } return Body.Eval(lambdaContext); } public override string ToString() { var sb = new StringBuilder(); sb.Append(Name).Append('('); using (var e = Parameters.GetEnumerator()) { if (e.MoveNext()) { sb.Append(e.Current.Name); while (e.MoveNext()) { sb.Append(','); sb.Append(e.Current.Name); } } } sb.Append(")=").Append(Body.ToString()); return sb.ToString(); } }