ValeraT1982 / ObjectsComparer

C# Framework provides mechanism to compare complex objects, allows to override comparison rules for specific properties and types.
MIT License
351 stars 86 forks source link

Ignoring leading/trailing whitespaces in comparison as a general rule #24

Closed rsaeed-volvocars closed 3 years ago

rsaeed-volvocars commented 3 years ago

Hi,

I would like to know the easiest way to ignore leading/trailing whitespaces when doing the comparison. I do not want to set this rule for individual properties but adding it as a general rule.

So "Test" and "Test " should not return a difference. And this should be done for all the properties rather than hardcoding for each property.

Regards, Riz

ValeraT1982 commented 3 years ago

@rsaeed-volvocars, you can override comparison rule for a string type. See https://github.com/ValeraT1982/ObjectsComparer#overriding-comparison-rules for more details.

rsaeed-volvocars commented 3 years ago

Well I had a struggle with it when I used it in the Factory. It always threw AmbiguousComparerOverrideResolutionException even though there was only one comparer for type string.

public class MyComparersFactory : ComparersFactory {

public override IComparer<T> GetObjectsComparer<T>(ComparisonSettings settings = null,
    BaseComparer parentComparer = null)    
{

    IComparer<T> comparer;
    if (typeof(T) != typeof(IList<FormulaItem>))

    {
        comparer = (IComparer<T>)base.GetObjectsComparer<T>(settings, parentComparer);
    }
    else

    {
        comparer = (IComparer<T>) new CustomFormulaItemsComparer(settings, parentComparer, this);
    }
    **comparer.AddComparerOverride(typeof(string), new MyValueComparer());**
    return comparer;
}

}

However it worked fine when I put the override in the CustomFormulaItemsComparer itself.

public class CustomFormulaItemsComparer : AbstractComparer<IList> {

public CustomFormulaItemsComparer(ComparisonSettings settings, BaseComparer parentComparer, IComparersFactory factory) : base(settings, parentComparer, factory) 
{
}

public override IEnumerable<Difference> CalculateDifferences(IList<FormulaItem> obj1, IList<FormulaItem> obj2)
{
    if (obj1 == null && obj2 == null)
    {
        yield break;
    }

    if (obj1 == null || obj2 == null)
    {
        yield return new Difference("", DefaultValueComparer.ToString(obj1), DefaultValueComparer.ToString(obj2));
        yield break;
    }

    if (obj1.Count != obj2.Count)
    {
        yield return new Difference("Count", obj1.Count.ToString(), obj2.Count.ToString(),
                DifferenceTypes.NumberOfElementsMismatch);
    }

    foreach (var formulaItem in obj1)
    {
        var formulaItem2 = obj2.FirstOrDefault(fi => fi.Id == formulaItem.Id);

        if (formulaItem2 != null)
        {
            var comparer = Factory.GetObjectsComparer<FormulaItem>();
           **comparer.AddComparerOverride(typeof(string), new MyValueComparer());**

            foreach (var difference in comparer.CalculateDifferences(formulaItem, formulaItem2))
            {
                yield return difference.InsertPath($"[Id={formulaItem.Id}]");
            }
        }
    }
}

}

To me it seemed more reasonable to add the override in the factory but it did not work.

ValeraT1982 commented 3 years ago

@rsaeed-volvocars I'll have a look. You can try AddComparerOverride only if parentComparer==null

ValeraT1982 commented 3 years ago

@rsaeed-volvocars, it works. Look here