C# - 具有嵌套复杂属性(如list和iEnumeable)的对象审计的通用方法

时间:2016-07-12 14:56:01

标签: c# asp.net generics reflection audit-logging

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

但是当谈到列表,数组等复杂数据类型时,我需要跟踪添加或删除的列表中的元素数量。我试图使用下面的代码弄清楚相同但是有点困在复杂的类型。

在每个循环中,它为我提供了对象类型的newItem和OldItem。无法执行其他操作。

我需要一些解决方案来从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;
    }

1 个答案:

答案 0 :(得分:0)

旧的预通用System.Collections.*接口仍然用于:使用对泛型集合的反射。

您可以将任何通用System.Collections.Generic.IEnumerable<T>投射到System.Collections.IEnumerable,任意System.Collections.Generic.IList<T>投放到System.Collections.IList等等。然后您可以以他们支持的任何方式循环播放它们。

您已经调用o.GetType().GetGenericArguments()以确保它们是相同类型的集合,如果是,您可以通过非泛型集合接口获取集合中的对象。当你拿到物品后,当然只需要递归。

相关问题