private static void Members <T>(T source, T target, MemberSettings settings, ReferencePairCollection referencePairs) { Debug.Assert(source != null, nameof(source)); Debug.Assert(target != null, nameof(target)); Debug.Assert(source.GetType() == target.GetType(), "Must be same type"); using (var borrowed = ListPool <IGetterAndSetter> .Borrow()) { foreach (var member in settings.GetMembers(source.GetType())) { if (settings.IsIgnoringMember(member)) { continue; } var getterAndSetter = settings.GetOrCreateGetterAndSetter(member); Member(source, target, settings, referencePairs, getterAndSetter); if (getterAndSetter.IsInitOnly) { borrowed.Value.Add(getterAndSetter); } } foreach (var getterAndSetter in borrowed.Value) { var sv = getterAndSetter.GetValue(source); var tv = getterAndSetter.GetValue(target); if (!EqualBy.MemberValues(sv, tv, settings)) { Throw.ReadonlyMemberDiffers(new SourceAndTargetValue(source, sv, target, tv), getterAndSetter.Member, settings); } } } }
internal static TypeErrorsBuilder VerifyRecursive( this TypeErrorsBuilder typeErrors, Type type, MemberSettings settings, MemberPath memberPath, Func <MemberSettings, MemberPath, TypeErrors> getPropertyErrors) { if (settings.ReferenceHandling == ReferenceHandling.References) { return(typeErrors); } typeErrors = VerifyEnumerableRecursively(typeErrors, type, settings, memberPath, getPropertyErrors); foreach (var member in settings.GetMembers(type)) { if (settings.IsIgnoringMember(member)) { continue; } if (memberPath == null) { memberPath = new MemberPath(type); } typeErrors = VerifyMemberRecursively(typeErrors, type, settings, memberPath, getPropertyErrors, member); } return(typeErrors); }
internal static bool MemberValues <T>( T x, T y, MemberSettings settings, ReferencePairCollection referencePairs) { bool result; if (TryGetValueEquals(x, y, settings, out result)) { return(result); } referencePairs?.Add(x, y); if (x is IEnumerable) { if (!EnumerableEquals(x, y, settings, referencePairs)) { return(false); } } foreach (var member in settings.GetMembers(x.GetType())) { if (settings.IsIgnoringMember(member)) { continue; } var getterAndSetter = settings.GetOrCreateGetterAndSetter(member); bool equal; object yv; object xv; if (getterAndSetter.TryGetValueEquals(x, y, settings, out equal, out xv, out yv)) { if (!equal) { return(false); } continue; } if (member.MemberType().IsClass&& referencePairs?.Contains(xv, yv) == true) { continue; } if (!MemberValueEquals(xv, yv, member, settings, referencePairs)) { return(false); } } return(true); }
private static void Member <T>( T source, T target, MemberSettings settings, ReferencePairCollection referencePairs, MemberInfo member) { if (settings.IsIgnoringMember(member)) { return; } var getterAndSetter = settings.GetOrCreateGetterAndSetter(member); Member(source, target, settings, referencePairs, getterAndSetter); }
internal static void Member <T>( T source, T target, MemberSettings settings, MemberInfo member) where T : class { if (settings.IsIgnoringMember(member)) { return; } using (var borrowed = settings.ReferenceHandling == ReferenceHandling.Structural ? ReferencePairCollection.Borrow() : null) { Member(source, target, settings, borrowed?.Value, member); } }
internal static void UpdateMemberDiff( this DiffBuilder builder, object xSource, object ySource, MemberInfo member, MemberSettings settings) { if (settings.IsIgnoringMember(member)) { return; } var getterAndSetter = settings.GetOrCreateGetterAndSetter(member); if (getterAndSetter.TryGetValueEquals(xSource, ySource, settings, out var equal, out var xValue, out var yValue)) { if (equal) { builder.Remove(member); } else { builder.TryAdd(member, xValue, yValue); } return; } switch (settings.ReferenceHandling) { case ReferenceHandling.References: if (ReferenceEquals(xValue, yValue)) { builder.Remove(member); } else { builder.TryAdd(member, xValue, yValue); } return; case ReferenceHandling.Structural: IRefCounted <DiffBuilder> subDiffBuilder; if (DiffBuilder.TryCreate(xValue, yValue, settings, out subDiffBuilder)) { subDiffBuilder.Value.UpdateDiffs(xValue, yValue, settings); } builder.AddLazy(member, subDiffBuilder.Value); return; case ReferenceHandling.Throw: throw Throw.ShouldNeverGetHereException(); default: throw new ArgumentOutOfRangeException( nameof(settings.ReferenceHandling), settings.ReferenceHandling, null); } }
internal static TypeErrorsBuilder VerifyRecursive( this TypeErrorsBuilder typeErrors, Type type, MemberSettings settings, MemberPath memberPath, Func<MemberSettings, MemberPath, TypeErrors> getPropertyErrors) { if (settings.ReferenceHandling == ReferenceHandling.References) { return typeErrors; } typeErrors = VerifyEnumerableRecursively(typeErrors, type, settings, memberPath, getPropertyErrors); foreach (var member in settings.GetMembers(type)) { if (settings.IsIgnoringMember(member)) { continue; } if (memberPath == null) { memberPath = new MemberPath(type); } typeErrors = VerifyMemberRecursively(typeErrors, type, settings, memberPath, getPropertyErrors, member); } return typeErrors; }