2013-05-16 48 views
0

我正在尝试编写一个泛型方法来对用户定义的对象(可能(几乎总是)有几个嵌套级别)进行成员比较。我正在找一个发现here的例子,它有一点小小的扭曲;如果该属性不能与相等运算符(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而不是更具体的类型。

编辑:编译器错误是好老“最佳重载方法具有一些无效的ARGS”

回答

1

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

有趣的是,你并不真的需要它是通用的 - 你使用反射来探索类型,而且你不需要实际的参数编译时间类型。只要给双方的行为和实验的iCommonObject类型和编辑将通过

+0

Upvoted,因为这基本上是正确的。但'pTypes'中没有任何类型实现'ICommonObject',所以我不确定ICommonObject在这里应该做什么......?看起来像“对象”是所有需要或将工作。 –

+0

@DominicP - 你是对的,先生。根据发布对象中的代码示例,此处应该足够了 – mfeingold

+0

@DominicP ICommonObject是我们定义的所有对象实现的接口。 pType中的对象是可以与相等运算符进行比较的“基元类型”。包含检查是为了确保当前的属性重载==或对其有本地支持。如果它不是,那么我知道它是我们的一个对象,所以我需要再次调用'MemberWiseCompare'与该对象,因此它是“原始类型”可以进行比较。 – evanmcdonnal

0

这应该工作:

的String [] innerErrors = MemberWiseCompare(pi.GetValue(ACT,空),pi.GetValue(EXP,空));