2015-08-25 96 views
0

我有遍历一个类并检查2个对象是否具有相同值的方法。通过对象的递归反射

private bool LoopThroughObjects<T>(T ob1, T ob2) 
{ 
    Type type = ob1.GetType(); 
    System.Reflection.PropertyInfo[] props = type.GetProperties(); 

    foreach (var prop in props) 
    { 
     object ent1value = prop.GetValue(ob1, new object[] { }); 
     object ent2value = prop.GetValue(ob2, new object[] { }); 

     //If object is in the same namespace it's a nested element 
     if(IsSameNameSpace(type.Namespace, prop.PropertyType.Namespace)) 
     { 
      _depth++; 
      ValidateEntity_AttributesNotSame(ent1value, ent2value); 
     } 
     else 
      ComparerOutput.Add(_conjunction + prop.Name, ent1value.Equals(ent2value)); 

     if (BreakOnUnequally) 
      if (!ent1value.Equals(ent2value)) 
       return false; 
    } 
    return true; 
} 

对象的例子,我可以送:

public class RefelctionTestEntity 
{ 
    public int Id { get; set; } 
    public String Firstname { get; set; } 
    public String Lastname { get; set; } 
    public int Age { get; set; } 
    public RefelctionTestEntity Child { get; set;} 
    public Vehicle.Bikes Bike { get; set; } 
} 

我走递归检查对象,所以我也将检查Child恩的Bike。我的问题是检查这些内部对象的最佳方法是什么? 我在这个时刻做的是检查对内部对象的父命名空间中的物体的命名空间:

private bool IsSameNameSpace(String baseNamespace, String propertyNamespace) 
{ 
    if (String.IsNullOrEmpty(baseNamespace) || String.IsNullOrEmpty(propertyNamespace)) 
     return true; 

    if (String.IsNullOrEmpty(baseNamespace) || String.IsNullOrEmpty(propertyNamespace)) 
     return false; 

    String[] part = propertyNamespace.Split('.'); 
    return part[0].Equals(baseNamespace); 
} 
+0

你是什么意思的“嵌套元素”?你不太清楚你想通过命名空间强加什么语义,但它可能不合适...... –

+2

首先你应该检查'obj1'和'obj2'是否是相同的类型。如果'obj1'是'obj2'的子类型并且引入了一个新属性,那么您的代码将失败。将'obj1.GetType()'改为'typeof(T)'将解决这个问题。为什么你需要测试命名空间?使用'Type.IsValueType',如果它不是递归地调用这个方法。 –

+0

同意@Verarind,但它是更复杂的问题 - 你还必须跟踪你已经比较的属性;否则你会以无尽的递归结束 - 如果你有var foo = new RefelctionTestEntity(); foo.Child = foo;你有麻烦了。看看http://stackoverflow.com/questions/6276439/how-to-compare-complex-objects-as-structures-in-c-sharp-for-unit-tests –

回答

0
//If object is in the same namespace it's a nested element 

使用这样的规则可能很快成为未来的一个问题。

如果使用接口标记递归项属性并检查当前属性是否实现该接口,将会更加方便。如果是这样,就深入一层。

否则检查您当前正在查看的属性的值是否与两个对象匹配。

var interf = Text.GetType().GetInterface("MyInterface",false); 

另一种方法是在项目上使用属性来标记它。

的属性的检查应该是这样的:

var att = Text.GetType().GetCustomAttributes(typeof(RecursiveTypeAttribute),false); 

我不会检查当前的属性是引用类型,因为你可以很容易地在今后引进的引用类型属性。