public static BlockExpression MergeBlocks(Expression expr1, Expression expr2) { IEnumerable <ParameterExpression> variables = new ParameterExpression[0]; IEnumerable <Expression> body = new Expression[0]; if (expr1 is BlockExpression block1) { body = body.Concat(block1.Expressions); variables = variables.Concat(block1.Variables); } else { body = body.Append(expr1); } if (expr2 is BlockExpression block2) { body = body.Concat(block2.Expressions); variables = variables.Concat(block2.Variables); } else { body = body.Append(expr2); } return(Block(variables.Distinct(), body)); }
private static TDelegate DelegateIndexerSet <TDelegate>(Type source, Type returnType, params Type[] indexTypes) where TDelegate : class { //TODO: check if returnType value is correct var indexerInfo = source.GetIndexerPropertyInfo(indexTypes); if (indexerInfo?.SetMethod == null) { return(null); } ParameterExpression sourceObjectParam; if (source.IsClassType() || source.GetTypeInfo().IsInterface) { sourceObjectParam = Expression.Parameter(typeof(object), "source"); } else { sourceObjectParam = Expression.Parameter(typeof(object).MakeByRefType(), "source"); } var valueParam = Expression.Parameter(returnType, "value"); var indexExpressions = new ParameterExpression[indexTypes.Length]; for (var i = 0; i < indexTypes.Length; i++) { var indexType = indexTypes[i]; indexExpressions[i] = Expression.Parameter(indexType, "i" + i); } var callArgs = indexExpressions.Concat(new[] { valueParam }).ToArray(); var paramsExpressions = new[] { sourceObjectParam }.Concat(callArgs); Expression blockExpr; if (!(source.IsClassType() || source.GetTypeInfo().IsInterface)) { #if !NET35 var structVariable = Expression.Variable(source, "struct"); blockExpr = Expression.Block(typeof(object), new[] { structVariable }, Expression.Assign(structVariable, Expression.Convert(sourceObjectParam, source)), Expression.Call(structVariable, indexerInfo.SetMethod, callArgs), Expression.Assign(sourceObjectParam, Expression.Convert(structVariable, typeof(object))) ); #else throw new ArgumentException("This is not supported for structures in .NET 3.5"); #endif } else { blockExpr = Expression.Call(Expression.Convert(sourceObjectParam, source), indexerInfo.SetMethod, callArgs); } return(Expression.Lambda <TDelegate>(blockExpr, paramsExpressions).Compile()); }
// Indexer Set private static Delegate DelegateIndexerSet(Type source, Type valueType, params Type[] indexTypes) { var propertyInfo = source.GetProperty(Item, valueType, indexTypes); if (propertyInfo == null) { return(null); } var sourceObjectParam = Expression.Parameter(typeof(object), "source"); var valueParam = Expression.Parameter(valueType, "value"); var indexExpressions = new ParameterExpression[indexTypes.Length]; for (var i = 0; i < indexTypes.Length; i++) { indexExpressions[i] = Expression.Parameter(indexTypes[i], "index"); } var callArgs = indexExpressions.Concat(new[] { valueParam }).ToArray(); var paramsExpressions = new[] { sourceObjectParam }.Concat(callArgs).ToArray(); return(Expression.Lambda(Expression.Call(Expression.Convert(sourceObjectParam, source), propertyInfo.GetSetMethod(), callArgs), paramsExpressions).Compile()); }