/// <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));
        }
Пример #2
0
        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));
        }