Home > Mobile >  C# - Compare an anonymous object with a normal object with same properties
C# - Compare an anonymous object with a normal object with same properties

Time:01-31

Using C#, is there any way I can compare and check if an anonymous object is equal to a normal object if both of them have the same properties?

For example:

    User normalUser = new() { Id = 1, Email = "[email protected]", LastLogin = DateTime.Now };
    var anonymousUser = new { Id = 1, Email = "[email protected]", LastLogin = DateTime.Now };

    if (normalUser == anonymousUser) // This comparison gives an error
    {
        Console.WriteLine("Both are same.");
    }

CodePudding user response:

Reflection is the way to go. But there are several implementations out there, one easy to use solution is the CompareNETObjects nuget package:

CompareLogic comparer = new CompareLogic(new ComparisonConfig { IgnoreObjectTypes = true });

if (comparer.Compare(normalUser, anonymousUser).AreEqual)
{
    Console.WriteLine("Both are same.");
}

CodePudding user response:

Below is a sample implementation using reflection that satisfies your question. Note that for a more thorough implementation you should probably use a well-established library specialized in this kind of stuff. You may refer to @jeroenh's answer.

using System.Reflection;

DateTime lastLogin = DateTime.Now;
User normalUser = new() { Id = 1, Email = "[email protected]", LastLogin = lastLogin };
var anonymousUser = new { Id = 1, Email = "[email protected]", LastLogin = lastLogin };

if (ReflectionUtils.AreObjectsEqualByProperty(normalUser, anonymousUser))
{
    Console.WriteLine("Both are same.");
}

public class User
{
    public int Id { get; init; }
    public string Email { get; init; }
    public DateTime LastLogin { get; init; }
}

public static class ReflectionUtils
{
    public static bool AreObjectsEqualByProperty(object? a, object? b)
    {
        const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public;

        if (a is null && b is null)
            return true;
        if (a is null || b is null)
            return false;

        Type aType = a.GetType();
        Type bType = b.GetType();
        PropertyInfo[] aProperties = aType.GetProperties(Flags);
        foreach (PropertyInfo aProperty in aProperties)
        {
            PropertyInfo? bProperty = bType.GetProperty(aProperty.Name, Flags);
            // one of a's properties is not present on b
            if (bProperty is null)
                return false;

            object? aValue = aProperty.GetValue(a);
            object? bValue = bProperty.GetValue(b);

            // property values are different
            if (!Equals(aValue, bValue))
                return false;
        }

        // Does b have extra properties that are not present on a?
        bool bHasExtraProperties = bType
            .GetProperties(Flags)
            .Any(bProperty => aProperties.FirstOrDefault(aProperty => aProperty.Name == bProperty.Name) is null);

        return !bHasExtraProperties;
    }
}
  •  Tags:  
  • Related