lundi 30 mai 2016

Compare two objects using reflection

I have any classes :

public class Store
{
    public string id { get; set; }

    public List<Customer> Customer { get; set; }
}

public class Customer
{
    public string FirstName { get; set; }

    public string LastName { get; set; }

    public List<Product> Product { get; set; }
}

public class Product
{
    public int ProductNumber { get; set; }

    public string ProductColor { get; set; }
}

And two instances :

Store Store1 = new Store
{
    id = "id1",
    Customer = new List<Customer>
    { 
        new Customer()
        {
            FirstName = "FirstName1",
            LastName = "LastName1",
            Product = new List<Product>
            {
                new Product()
                {
                    ProductColor = "ProductColor1",
                    ProductNumber = 1
                }
            }
        }
    }
};

Store Store2 = new Store
{
    id = "id2",
    Customer = new List<Customer>
    { 
        new Customer()
        {
            FirstName = "FirstName1",
            LastName = "LastName1",
            Product = new List<Product>
            {
                new Product()
                {
                    ProductColor = "ProductColor1",
                    ProductNumber = 2
                }
            }
        }
    }
};

I have a method who compare two objects with reflection :

public static bool AreEquals(object objectA, object objectB)
{
    if (objectA != null && objectB != null)
    {
        Type objectType = objectA.GetType();

        foreach (PropertyInfo propertyInfo in objectType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(x => x.CanRead))
        {
            object valueA = propertyInfo.GetValue(objectA, null);
            object valueB = propertyInfo.GetValue(objectB, null);

            if (typeof(IComparable).IsAssignableFrom(propertyInfo.PropertyType) ||
                propertyInfo.PropertyType.IsPrimitive ||
                propertyInfo.PropertyType.IsValueType)
            {
                if (!AreValuesEqual(valueA, valueB))
                    Console.WriteLine(string.Format("{0}.{1} not equal : {2} != {3} ", propertyInfo.ReflectedType.Name, propertyInfo.Name, valueA, valueB));
            }

            else if (typeof(IEnumerable).IsAssignableFrom(propertyInfo.PropertyType))
            {
                else if (valueA != null && valueB != null)
                {
                    IEnumerable<object> collectionItems1 = ((IEnumerable)valueA).Cast<object>();
                    IEnumerable<object> collectionItems2 = ((IEnumerable)valueB).Cast<object>();

                    for (int i = 0; i < collectionItems1.Count(); i++)
                    {
                        Console.WriteLine("{0}.{1}[{2}]", propertyInfo.ReflectedType.Name, propertyInfo.Name, i);

                        object collectionItem1 = collectionItems1.ElementAt(i);
                        object collectionItem2 = collectionItems2.ElementAt(i);
                        Type collectionItemType = collectionItem1.GetType();

                        if (typeof(IComparable).IsAssignableFrom(collectionItemType) ||
                            collectionItemType.IsPrimitive ||
                            collectionItemType.IsValueType)
                        {
                            if (!AreValuesEqual(collectionItem1, collectionItem2))
                                return false;
                        }
                        else if (!AreEquals(collectionItem1, collectionItem2))
                            return false;
                    }                   
                }
            }

            else if (propertyInfo.PropertyType.IsClass)
            {
                if (!AreEquals(propertyInfo.GetValue(objectA, null), propertyInfo.GetValue(objectB, null)))
                    return false;
            }
            else
            {
                Console.WriteLine("Cannot compare property '{0}.{1}'.", propertyInfo.ReflectedType.Name, propertyInfo.Name);
                return false;
            }
        }
        return true;
    }
    return false;
}

This method return :

enter image description here

But I want to get the full path of the property :

enter image description here

How to do this ? Or what is the best way to do this ?





Aucun commentaire:

Enregistrer un commentaire