C# 使用反射比较列表中的对象
我有一个“Invoice”WinForm C,其中包含常用的文本框和未绑定的datagridview。 我使用“Invoice”类对象来存储表单字段的值。datagridview行存储在“发票”中的列表<子发票>属性中C# 使用反射比较列表中的对象,c#,winforms,reflection,C#,Winforms,Reflection,我有一个“Invoice”WinForm C,其中包含常用的文本框和未绑定的datagridview。 我使用“Invoice”类对象来存储表单字段的值。datagridview行存储在“发票”中的列表属性中 public static bool CompareObjects(object original, object altered) { Type o = original.GetType(); Type a = altered.GetType(); foreac
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;
}
我正在使用一个全局类和一个方法,该方法使用反射来循环原始“invoice”对象,并将其与修改后的“invoice”进行比较。如果有任何差异,将通知用户保存发票
上面的方法适用于“Invoice”类的所有属性,但我不知道如何检查列表,在该列表中,它将每个datagridrow的值存储到一个“SubInvoice”类对象中,该对象将其存储为列表中的一个对象
有人能帮我一下吗?我也在stackoverflow和其他论坛中检查过类似的线程,但没有结果
更新:我需要创建一个全局泛型方法来检查所有类型的类。它可以是“发票”、“客户”。其目的是跟踪在任何特定实例中对表单所做的任何更改,并提示用户进行保存。如果您只是想通知用户保存挂起的更改,那么您应该实现,而不是执行一些黑魔法。我以前见过的一个技巧是将对象标记为可序列化,然后将它们序列化为字符串并比较字符串。它可能不是最有效的方法,但它快速、简单,适用于几乎任何类型的数据类。它甚至适用于引用其他类的复杂嵌套类
一个不利的一面是,它不会轻易告诉你具体发生了什么变化,只是有些不同。谢谢大家的帮助 我无意中读到了下面的文章,但仍然渴望通过反射创建一个全局通用方法 如果有人感兴趣,这里有代码
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;
}
用法:如果!xx.比较对象搜索语音,更改语音|!xx.CompareListssearchedInvoice.SubInvoice,alteredVoice.SubInvoice如果o和a是不同的类型,则此代码将引发异常,除非a恰好具有与o相同的所有属性。如果任何属性是类或结构,它也不会像您所希望的那样工作,除非它们碰巧重载了ToString以返回一个可以用作相等比较的值。最后,如果a有o没有的属性,它将无法检测到可能的差异。当然可以。o和a都是相同的发票对象。唯一的区别是它们所持有的价值观。例如,o在“原始”中可能有$300.25作为“双倍totalAmount”属性的总值,而a在“更改”中可能有$525.16作为同一属性字段中的总值。“Invoice”类具有double、int、datetime属性和一个List