0

我正在尝试编写一个通用方法来对用户定义的对象进行成员比较,这些对象可能(几乎总是)具有多个嵌套级别。我正在处理这里找到的示例,但有一点点扭曲;如果该属性不能与相等运算符(pTypes 数组中的那些)进行比较,那么我想进行一个递归调用,传入当前属性。我的代码无法编译,我在递归调用中尝试了各种语法,我只是想知道什么是正确的语法?或者你能做到这一点吗?

这是我现在的方法;

    public static string[] MemberWiseCompare<T>(T act, T exp) where T : ICommonObject
    {
        List<string> errors = new List<string>();

        if (act != null && exp != null)
        {
            Type[] pTypes = { typeof(int), typeof(bool), typeof(string), typeof(float), typeof(double), typeof(DateTime) };
            Type type = typeof(T);
            foreach (PropertyInfo pi in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
            {
                if (pTypes.Contains(pi.PropertyType))
                {
                    if (type.GetProperty(pi.Name).GetValue(act, null) != type.GetProperty(pi.Name).GetValue(exp, null))
                    {
                        errors.Add(pi.Name);
                    }
                }
                else
                {
                    string[] innerErrors = MemberWiseCompare<pi.PropertyType>(pi.GetValue(act, null), pi.GetValue(exp, null));
                }
            }
        }
        return null;
    }

当然,我还没有实现该方法的其他部分(在函数底部聚合错误并返回 null 以外的内容),但目前我只关心让递归MemberWiseCompare工作。从那里我可以弄清楚其余的。我想我在理解编译器从我为泛型指定的类型(即 pi.PropertyType )中带走了什么时遇到了一些问题。我认为这会起作用,因为它提供了我们将在通用调用中使用的类型。我也预料到它将我的值装箱会出现一些问题,以便GetValue返回一个object而不是更具体的类型。

编辑:编译器错误是古老的“最佳重载方法有一些无效的参数”

4

2 回答 2

1

它无法编译,因为通用参数值必须在编译时可用。在对 MemberWiseCompare 的内部调用中,您试图将一个仅在运行时可用的值传递给它。

有趣的是,您实际上并不需要它是通用的 - 您使用反射来探索类型,并且您不需要编译时参数的实际类型。只需将 act 和 exp 都指定为 iCommonObject 类型,编译将通过

于 2013-05-16T21:22:41.613 回答
0

这应该有效:

string[] innerErrors = MemberWiseCompare(pi.GetValue(act, null), pi.GetValue(exp, null));

于 2013-05-16T21:30:01.053 回答