C# - 用于对象审核的通用方法,具有嵌套的复杂属性,如列表和 iEnumeable

本文关键字:复杂 嵌套 属性 iEnumeable 列表 方法 对象 用于 | 更新日期: 2023-09-27 17:56:29

我正在尝试创建一个通用方法,该方法将两个对象作为参数,并比较对象中的每个属性并返回差异。现在我正在使用反射实现这一点,这对于简单的属性(int,string....)工作正常。

但是当涉及到复杂的数据类型,如列表、数组等时。我需要跟踪添加或删除的列表中元素的数量。我正在尝试使用以下代码找出相同的问题,但对于复杂类型来说有点卡住了。

在每个循环中,它都给了我对象类型的新项和旧项。无法执行其他操作。

我需要一些解决方案来查找从 IEnumerable 类型属性中添加和删除的项目。

任何建议,不胜感激。

谢谢!!

 private static string GenerateAuditLogMessage<T>(T oldObject, T newObject)
    {
        PropertyInfo[] properties = typeof(T).GetProperties();
        foreach (PropertyInfo pi in properties)
        {
            object oldValue = pi.GetValue(oldObject), newValue = pi.GetValue(newObject);
            if (pi.PropertyType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(pi.PropertyType))
            {
                Type type = oldValue.GetType().GetGenericArguments()[0];
                foreach (var oldItem in (IEnumerable)oldValue)
                {
                    foreach (var newItem in (IEnumerable)newValue)
                    {
                        var propertyResult = GenerateAuditLogMessage<object>(oldObject, newObject);
                        if (string.IsNullOrEmpty(propertyResult))
                        {
                            // newItem. 
                        }
                    }
                }
                /* Need something like below commented line.*/
                // var added = newValue.Except(oldValue)
                // var removed = oldValue.Except(newValue);
            }
            else
            {
                if (!object.Equals(oldValue, newValue))
                {
                    //....
                }
            }
        }
        return string.Empty;
    }

C# - 用于对象审核的通用方法,具有嵌套的复杂属性,如列表和 iEnumeable

这是旧的泛型前System.Collections.*接口仍然用于的一件事: 对泛型集合使用反射。

您可以将任何泛型System.Collections.Generic.IEnumerable<T>转换为System.Collections.IEnumerable,任何System.Collections.Generic.IList<T>转换为System.Collections.IList,等等。然后,您可以以它们支持的任何方式循环访问它们。

你已经调用了o.GetType().GetGenericArguments()以确保它们是相同类型的集合,如果是,则可以通过非泛型集合接口获取集合中的对象。当然,一旦你得到了对象,就递归了。