/// <summary> /// Gets diff of two property containers. /// </summary> public static ObjectDiff GetDiff( IPropertyContainer container1, IPropertyContainer container2, Func <IPropertyValue, string>?renderValue = null, bool compareByRenderedValues = false, SearchOptions?searchOptions = null) { renderValue ??= FormatForDiff; var search = searchOptions ?? Search.ExistingOnlyWithParent.WithPropertyComparer(PropertyComparer.ByTypeAndNameComparer); IEnumerable <(IPropertyValue?PropertyValue1, IPropertyValue PropertyValue2)> propertyPairs = container2 .Properties .Select(propertyValue2 => (container1.GetPropertyValueUntyped(propertyValue2.PropertyUntyped, search), propertyValue2)); IEnumerable <(IPropertyValue PropertyValue1, IPropertyValue?PropertyValue2)> removedPropertyPairs = container1 .Properties .Select(propertyValue1 => (propertyValue1, container2.GetPropertyValueUntyped(propertyValue1.PropertyUntyped, search))) .Where(tuple => tuple.Item2 == null); var propertyPairsAll = propertyPairs.Concat(removedPropertyPairs); PropertyDiff[]? diffPairs; if (compareByRenderedValues) { diffPairs = propertyPairsAll .Select(propertyPair => PropertyDiff(propertyPair)) .Where(diff => !Equals(diff.NewValue, diff.OldValue)) .ToArray(); } else { diffPairs = propertyPairsAll .Where(propertyPair => !EqualsForDiff(propertyPair.PropertyValue1?.ValueUntyped, propertyPair.PropertyValue2?.ValueUntyped)) .Select(propertyPair => PropertyDiff(propertyPair)) .ToArray(); } PropertyDiff PropertyDiff((IPropertyValue? PropertyValue1, IPropertyValue? PropertyValue2) valueTuple) { string propertyName = (valueTuple.PropertyValue1?.PropertyUntyped.Name ?? valueTuple.PropertyValue2?.PropertyUntyped.Name) !; return(new PropertyDiff( propertyName, valueTuple.PropertyValue1 != null ? renderValue(valueTuple.PropertyValue1) : null, valueTuple.PropertyValue2 != null? renderValue(valueTuple.PropertyValue2) : null)); } return(new ObjectDiff(diffPairs)); }
/// <inheritdoc /> public override bool TryGetMember(GetMemberBinder binder, [MaybeNullWhen(true)] out object result) { var propertyValue = _propertyContainer.GetPropertyValueUntyped(Search .ByNameOrAlias(binder.Name, _ignoreCase) .SearchInParent(_searchInParent) .ReturnNull()); if (propertyValue != null) { result = propertyValue.ValueUntyped; return(true); } // returns null if property was not found. result = null; return(true); }