/// <summary> /// If there is a MemberInitExpression 'new Person { ID = p.ID, Friend = new Person { ID = p.Friend.ID }}' /// or a NewExpression 'new { ID = p.ID, Friend = new { ID = p.Friend.ID }}', /// this method validates against the RHS of the member assignment, the expression "p.ID" for example. /// </summary> /// <param name="expressionToAssign">The expression to validate.</param> /// <param name="initType">Type of the MemberInit or the New expression.</param> /// <param name="previousNested">The outer nested initializer of the current initializer we are checking.</param> /// <returns>true if the expression to assign is fine; false otherwise.</returns> private bool CheckCompatibleAssignmentExpression(Expression expressionToAssign, Type initType, ref MemberAssignmentAnalysis previousNested) { MemberAssignmentAnalysis nested = MemberAssignmentAnalysis.Analyze(this.entity, expressionToAssign); if (nested.MultiplePathsFound) { this.multiplePathsFound = true; return(false); } // When we're visiting a nested entity initializer, we're exactly one level above that. Exception incompatibleException = nested.CheckCompatibleAssignments(initType, ref previousNested); if (incompatibleException != null) { this.incompatibleAssignmentsException = incompatibleException; return(false); } if (this.pathFromEntity.Count == 0) { this.pathFromEntity.AddRange(nested.GetExpressionsToTargetEntity()); } return(true); }
/// <summary> /// Checks whether the this and a <paramref name="previous"/> /// paths for assignments are compatible. /// </summary> /// <param name="targetType">Type being initialized.</param> /// <param name="previous">Previously seen member accesses (null if this is the first).</param> /// <returns>An exception to be thrown if assignments are not compatible; null otherwise.</returns> /// <remarks> /// This method does not set the IncompatibleAssignmentsException property on either /// analysis instance. /// </remarks> internal Exception CheckCompatibleAssignments(Type targetType, ref MemberAssignmentAnalysis previous) { if (previous == null) { previous = this; return(null); } Expression[] previousExpressions = previous.GetExpressionsToTargetEntity(); Expression[] candidateExpressions = this.GetExpressionsToTargetEntity(); return(CheckCompatibleAssignments(targetType, previousExpressions, candidateExpressions)); }
/// <summary> /// Checks whether the this and a <paramref name="previous"/> /// paths for assignments are compatible. /// </summary> /// <param name="targetType">Type being initialized.</param> /// <param name="previous">Previously seen member accesses (null if this is the first).</param> /// <returns>An exception to be thrown if assignments are not compatible; null otherwise.</returns> /// <remarks> /// This method does not set the IncompatibleAssignmentsException property on either /// analysis instance. /// </remarks> internal Exception CheckCompatibleAssignments(Type targetType, ref MemberAssignmentAnalysis previous) { if (previous == null) { previous = this; return null; } Expression[] previousExpressions = previous.GetExpressionsToTargetEntity(); Expression[] candidateExpressions = this.GetExpressionsToTargetEntity(); return CheckCompatibleAssignments(targetType, previousExpressions, candidateExpressions); }