private Expression Evaluate(Expression e) { Type type = e.Type; // check for nullable converts & strip them if (e.NodeType == ExpressionType.Convert) { var u = (UnaryExpression)e; if (AiTypeHelper.GetNonNullableType(u.Operand.Type) == AiTypeHelper.GetNonNullableType(type)) { e = ((UnaryExpression)e).Operand; } } // if we now just have a constant, return it if (e.NodeType == ExpressionType.Constant) { var ce = (ConstantExpression)e; // if we've lost our nullable typeness add it back if (e.Type != type && AiTypeHelper.GetNonNullableType(e.Type) == AiTypeHelper.GetNonNullableType(type)) { e = ce = Expression.Constant(ce.Value, type); } return(e); } var me = e as MemberExpression; if (me != null) { // member accesses off of constant's are common, and yet since these partial evals // are never re-used, using reflection to access the member is faster than compiling // and invoking a lambda var ce = me.Expression as ConstantExpression; if (ce != null) { return(Expression.Constant(me.Member.GetValue(ce.Value), type)); } } if (type.IsValueType) { e = Expression.Convert(e, typeof(object)); } Expression <Func <object> > lambda = Expression.Lambda <Func <object> >(e); #if NOREFEMIT Func <object> fn = ExpressionEvaluator.CreateDelegate(lambda); #else Func <object> fn = lambda.Compile(); #endif return(Expression.Constant(fn(), type)); }
public static object GetDefault(Type type) { bool isNullable = !type.IsValueType || AiTypeHelper.IsNullableType(type); if (!isNullable) { return(Activator.CreateInstance(type)); } return(null); }
protected override Expression VisitNewArray(NewArrayExpression na) { this.Write("new "); this.Write(this.GetTypeName(AiTypeHelper.GetElementType(na.Type))); this.Write("[] {"); if (na.Expressions.Count > 1) { this.WriteLine(Indentation.Inner); } this.VisitExpressionList(na.Expressions); if (na.Expressions.Count > 1) { this.WriteLine(Indentation.Outer); } this.Write("}"); return(na); }