/// <summary> /// Visit new expressions for structural data types and transforms occurrences of entity types. /// </summary> /// <param name="node">The expression to transform.</param> /// <param name="newType">The original type of the new expression.</param> /// <returns>The new expression with the original type replaced with the new type.</returns> protected virtual Expression VisitNewStructuralDataType(NewExpression node, StructuralTypeSlim newType) { if (node.Constructor is not DataModelConstructorInfoSlim oldConstructor || oldConstructor.ParameterMappings.Count != node.ArgumentCount) { throw new InvalidOperationException("Expected a constructor info instance with mapping attributes associated with constructor parameters."); } var n = oldConstructor.ParameterMappings.Count; var memberAssignments = new Dictionary <MemberInfo, Expression>(n); for (var i = 0; i < n; ++i) { var oldParameter = oldConstructor.ParameterMappings[i]; var oldArgument = node.GetArgument(i); var newProperty = newType.Properties.Single(p => p.Name == oldParameter); // TODO: remove allocation if (memberAssignments.ContainsKey(newProperty)) { throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Parameter mapping attribute '{0}' on the constructor of '{1}' is used more than once.", oldParameter, newType)); } var newArgument = Visit(oldArgument); memberAssignments[newProperty] = newArgument; } return(CreateNewExpression(newType, memberAssignments)); }
private object InvokeConstructor(NewExpression node) { int argCount = node.ArgumentCount(); object[] arguments = argCount > 0 ? new object[argCount] : Type.EmptyTypes; for (int i = 0; i < argCount; i++) { arguments[i] = EvaluateArgument(node.GetArgument(i)); } return(Activator.CreateInstance(node.Type, arguments)); }