【问题标题】:Recursive reflection through object通过对象的递归反射
【发布时间】:2015-11-18 20:21:24
【问题描述】:

我有一个方法可以遍历一个类并检查 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; }
}

我递归地遍历对象,因此我还将检查ChildBike。我的问题是检查这些内部对象的最佳方法是什么? 我现在要做的是对照内部对象的父命名空间检查对象的命名空间:

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);
}

【问题讨论】:

  • “嵌套元素”是什么意思?目前还不清楚您试图通过命名空间施加什么语义,但它可能不合适......
  • 首先你应该检查obj1obj2是否属于同一类型。如果 obj1obj2 的子类型并引入了新属性,则您的代码将失败。将obj1.GetType() 更改为typeof(T) 将解决该问题。为什么需要测试命名空间?使用Type.IsValueType,如果不是递归调用这个方法。
  • 同意@Verarind,但是这是一个更复杂的问题——你还必须跟踪你已经比较过的属性;否则你会以无休止的递归结束——如果你有 var foo = new RefelctionTestEntity(); foo.Child = foo;你有麻烦了。看stackoverflow.com/questions/6276439/…
  • @Verarind 您提供的检查已经完成,但是在另一个调用此方法的方法中。我检查名称空间以查看对象(儿童或自行车)是否是内部对象。 Type.IsValueType 始终为 false。
  • @Cageman 您的属性的所有返回类型都是引用类型?哇。你做了GetValue(obj1, null)。应该对ent1Valueent2Value 进行递归调用。

标签: c# recursion reflection


【解决方案1】:
//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);

我不会检查当前属性是否为引用类型,因为您将来可以轻松引入引用类型属性。

【讨论】:

    猜你喜欢
    • 2016-01-24
    • 2012-10-03
    • 2019-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-24
    • 1970-01-01
    相关资源
    最近更新 更多