// Creates a GeneratorLambda as a lambda containing a parameterless // generator. In the case where we return an IEnumerator, it's a very // simple, constant-time construction. However, if the result is // IEnumerable, it will perform a full tree walk to ensure that each // call to GetEnumerator() returns an IEnumerator with the same // values for the parameters. public static LambdaExpression GeneratorLambda( Type delegateType, LabelTarget label, Expression body, string name, bool rewriteAssignments, IEnumerable <ParameterExpression> parameters) { ContractUtils.RequiresNotNull(delegateType, "delegateType"); ContractUtils.Requires(delegateType.IsSubclassOf(typeof(MulticastDelegate)), "Lambda type parameter must be derived from System.Delegate"); Type generatorType = delegateType.GetMethod("Invoke").GetReturnType(); var paramList = parameters.ToReadOnly(); if (IsEnumerableType(generatorType)) { // rewrite body body = TransformEnumerable(body, paramList); } return(Expression.Lambda( delegateType, Utils.Generator(name, label, body, generatorType, rewriteAssignments), name, paramList )); }
protected override Expression VisitChildren(ExpressionVisitor visitor) { Expression b = visitor.Visit(_body); if (b == _body) { return(this); } return(Utils.Generator(_name, _target, b, Type)); }