/// <summary>
/// Creates a <see cref="WithCSharpExpression"/> that represents a with expression applied to an anonymous type.
/// </summary>
/// <param name="object">The expression representing the object to clone and mutate.</param>
/// <param name="members">The members of the anonymous type in the order of their assignment by the constructor parameters.</param>
/// <param name="initializers">The initializers used to mutate the cloned object.</param>
/// <returns>The created <see cref="WithCSharpExpression"/>.</returns>
public static WithCSharpExpression With(Expression @object, IEnumerable <MemberInfo> members, IEnumerable <MemberInitializer> initializers)
{
RequiresNotNull(@object, nameof(@object));
RequiresNotNull(members, nameof(members));
RequiresNotNull(initializers, nameof(initializers));
var membersCollection = members.ToReadOnly();
var initializersCollection = initializers.ToReadOnly();
ValidateWithReceiverAndInitializers(@object, initializersCollection, requiresCanAssign: false);
var membersCount = membersCollection.Count;
var newMembers = new MemberInfo[membersCount];
var memberTypes = new Type[membersCount];
for (var i = 0; i < membersCount; i++)
{
var member = membersCollection[i];
RequiresNotNull(member, nameof(member));
if (!AreEquivalent(member.DeclaringType, @object.Type))
{
throw LinqError.ArgumentMemberNotDeclOnType(member.Name, @object.Type.Name);
}
ValidateAnonymousTypeMember(ref member, out var memberType);
newMembers[i] = member;
memberTypes[i] = memberType;
}
membersCollection = newMembers.ToReadOnly();
var ctor = @object.Type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, binder: null, memberTypes, modifiers: null);
if (ctor == null)
{
throw Error.NoAnonymousTypeConstructorFound(@object.Type);
}
return(new WithCSharpExpression(@object, initializersCollection, clone: null, membersCollection));
}