简体   繁体   中英

Reflection: How will get difference IEnumerable properties?

I have a method that gets the difference between two objects of the same type. The method of the difference is stored in a new dynamic object. How to find the difference between the properties of IEnumerable?

Method Code:

public class TestDto
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Login { get; set; }
    public string Password { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public Guid PassportId { get; set; }
    public bool IsDeleted { get; set; }
    public bool IsNotFinded { get; set; }
    public bool IsInvited { get; set; }
    public bool IsAuctionIsCancelled { get; set; }
    public bool IsInvitationRequired { get; set; }
    public string Role { get; set; }
    public bool HasRetailerAccess { get; set; }
    public bool HasExtendedPaidAccess { get; set; }
    public bool HasRatesInPaidMode { get; set; }
    public string PersonalAdminName { get; set; }
    public int? PersonalAdminId { get; set; }
    public bool IsPremoderationAccepted { get; set; }
    public List<int> l { get; set; }

    public TestDto()
    {
        Id = 0;
        Name = "Test Name";
        Login = "Test Login";
        Password = "12345";
        Email = "test@mail.ru";
        PassportId = new Guid();
        IsDeleted = false;
        IsNotFinded = false;
        IsInvited = false;
        IsAuctionIsCancelled = false;
        IsInvitationRequired = false;
        HasRetailerAccess = false;
        HasExtendedPaidAccess = false;
        HasExtendedPaidAccess = false;
        HasRatesInPaidMode = false;
        IsPremoderationAccepted = false;
        l = new List <int> {5, 10, 15, 100};
    }
}


class Program
{
    static object DifferenceOfObjects(object objectNew, object objectOld)
    {
        dynamic expando = new ExpandoObject();
        var expandoDictionary = expando as IDictionary<String, object>;

        if (objectNew.GetType() != objectOld.GetType())
        {
            return expando;
        }
        var oType = objectOld.GetType();

        foreach (var oProperty in oType.GetProperties())
        {
            var oOldValue = oProperty.GetValue(objectOld, null);
            var oNewValue = oProperty.GetValue(objectNew, null);
            if (oNewValue is IEnumerable && !(oNewValue is string))
            {
                //Type IEnumerable property
                Type itemType = oNewValue.GetType().GetGenericArguments()[0];
                //How equals two IEnumerable property oOldValue and oNewValue...?
            }
            else
            if (!Equals(oOldValue, oNewValue))
            {
                expandoDictionary[oProperty.Name] = new { OldValue = oOldValue, NewValue = oNewValue };
            }
        }

        return expando;
    }

    static void Main(string[] args)
    {
        var oOldRecord = new TestDto();
        var oNewRecord = new TestDto();

        oNewRecord.Name = "Modifined";
        oNewRecord.PersonalAdminId = 100;
        oNewRecord.PassportId = Guid.NewGuid();

        var diffObj = DifferenceOfObjects(oNewRecord, oOldRecord);
        Console.ReadLine();
    }

TestDto - it is test class for comparison. DifferenceOfObjects - it is method which finds the difference between objects.

The easiest way would be:

bool areEqual = !list1.Except(list2).Any() && !list2.Except(list1).Any();

list1.Except(list2) retrieves all elements of list1 which are not in list2. Any() checks if there are elements in the result-list.

This way you check if no elements are not in the other list. Be aware that your generic-parameter has to override Equals() and GetHashCode() .

In order to get a generic version of the IEnumerable, you can use the Cast<object>() method.

To get the difference you can do something such as:

            var listAsObj1 = (list1 as IEnumerable).Cast<object>();
            var listAsObj2 = (list2 as IEnumerable).Cast<object>();

            var differences = listAsObj1.Except(listAsObj2)            // In 1 (not in 2)
                                .Concat(listAsObj2.Except(listAsObj1)) // In 2 (not in 1)
                                .Select(_ => _.ToString());            // As string values
    static object DifferenceOfObjects(object objectNew, object objectOld)
    {
        dynamic expando = new ExpandoObject();
        var expandoDictionary = expando as IDictionary<String, object>;

        if (objectNew.GetType() != objectOld.GetType())
        {
            return expando;
        }
        var oType = objectOld.GetType();

        foreach (var oProperty in oType.GetProperties())
        {
            var oOldValue = oProperty.GetValue(objectOld, null);
            var oNewValue = oProperty.GetValue(objectNew, null);

            if (Equals(oOldValue, oNewValue))
            {
                continue;
            }

            if (oNewValue is IEnumerable && oOldValue is IEnumerable)
            {
                var enumerableNew = (oNewValue as IEnumerable).Cast<object>();
                var enumerableOld = (oOldValue as IEnumerable).Cast<object>();

                if (enumerableOld.SequenceEqual(enumerableNew))
                {
                    continue;
                }
            }

            expandoDictionary[oProperty.Name] = new { OldValue = oOldValue, NewValue = oNewValue };
        }

        return expando;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM