使用反射来比较列表中的对象

时间:2014-10-20 03:17:42

标签: c# winforms reflection

我有一个'发票'WinForm C#,其中包含通常的文本框和未绑定的数据网格视图。 我使用'Invoice'类对象来存储表单字段的值。 datagridview行存储到List< SubInvoice> “发票”中的属性。

public static bool CompareObjects(object original, object altered)
{
    Type o = original.GetType();
    Type a = altered.GetType();

    foreach (PropertyInfo p in o.GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        Console.WriteLine("Original: {0} = {1}", p.Name, p.GetValue(original, null));
        Console.WriteLine("Altered: {0} = {1}", p.Name, p.GetValue(altered, null));

        if (p.GetValue(original, null).ToString() != p.GetValue(altered, null).ToString())
        {
            //Console.WriteLine("Not Equal");
            return false;
        }
    }

    return true;
}

我正在使用一个全局类,其方法使用Reflection来遍历原始的“invoice”对象,并将其与更改后的“invoice”进行比较。如果有任何差异,将通知用户保存发票。

上述方法适用于'Invoice'类的所有属性,但我不知道如何检查List,它将每个datagridrow的值存储到'SubInvoice'类对象中,该类对象将其存储为对象在列表中。

有人可以在这里给我一些帮助吗?我还检查了stackoverflow和其他论坛中的类似线程但是徒劳无功。

更新:我需要创建一个全局泛型方法来检查所有类型的类。它可以是“发票”,“客户”。目的是跟踪在任何特定实例中对表单所做的任何更改,并提示用户保存。

3 个答案:

答案 0 :(得分:0)

如果您只想通知用户保存待处理的更改,那么您应该实施INotifyPropertyChanged而不是做一些黑魔法。

答案 1 :(得分:0)

我之前看到的一个技巧是将对象标记为可序列化,然后将它们序列化为字符串并比较字符串。它可能不是最有效的方法,但它快速,简单,几乎适用于任何类型的数据类。它甚至适用于引用其他类的“复杂”嵌套类。

一个缺点是,它不会轻易告诉你具体改变了什么,只是有些不同。

答案 2 :(得分:0)

谢谢大家的帮助。

我偶然发现了以下文章,同时仍然渴望通过反思创建一个全局泛型方法。

http://www.c-sharpcorner.com/UploadFile/1a81c5/custom-extension-method-to-compare-list-in-C-Sharp/

如果有人有兴趣,这是代码。

public static bool CompareObjects(object original, object altered)
{
    bool result = true;

    //Get the class
    Type o = original.GetType();
    Type a = altered.GetType();

    //Cycle through the properties.
    foreach (PropertyInfo p in o.GetProperties(BindingFlags.Public | BindingFlags.Instance))
    {
        Console.WriteLine("Original: {0} = {1}", p.Name, p.GetValue(original, null));
        Console.WriteLine("Altered: {0} = {1}", p.Name, p.GetValue(altered, null));

        if (!p.PropertyType.IsGenericType)
        {
            if (p.GetValue(original, null) != null && p.GetValue(altered, null) != null)
            {
                if (!p.GetValue(original, null).ToString().Equals(p.GetValue(altered, null).ToString()))
                {
                    result = false;
                    break;
                }
            }
            else
            {
                //If one is null, the other is not
                if ((p.GetValue(original, null) == null && p.GetValue(altered, null) != null) || (p.GetValue(original, null) != null && p.GetValue(altered, null) == null))
                {
                    result = false;
                    break;
                }
            }
        }
    }

    return result;
}

public static bool CompareLists<T>(this List<T> original, List<T> altered)
{
    bool result = true;

    if (original.Count != altered.Count)
    {
        return false;
    }
    else
    {
        if (original != null && altered != null)
        {
            foreach (T item in original)
            {
                T object1 = item;
                T object2 = altered.ElementAt(original.IndexOf(item));

                Type objectType = typeof(T);

                if ((object1 == null && object2 != null) || (object1 != null && object2 == null))
                {
                    result = false;
                    break;
                }

                if (!CompareObjects(object1, object2))
                {
                    result = false;
                    break;
                }
            }
        }
        else
        {
            if ((original == null && altered != null) || (original != null && altered == null))
            {
                return false;
            }
        }
    }

    return result;
}

用法: if(!xx.CompareObjects(searchingInvoice,changedInvoice)|!xx.CompareLists(searchingInvoice.SubInvoice,changedInvoice.SubInvoice))