使用Linq找到嵌套属性?

时间:2013-03-27 20:51:54

标签: c# linq reflection lambda

我有一个如下所示的对象模型。

public class Class1
{
    public Class2 @Class2;
}

public class Class2
{
    public Class3 @Class3;
    public Class4 @Class4;
}

public class Class3
{
    public Class5 @Class5;
}

public class Class4
{
    public Class5 @Class5;
}

public class Class5
{
    public Class6 @Class6;
}

public class Class6
{
}

任何人都可以推荐一种迭代层次结构的方法,直到我可以获得Class5的实例,这是Class4的属性吗?在VS2012上使用.NET 4.5,C#。

2 个答案:

答案 0 :(得分:1)

这样做的典型方法是使用访客模式。在您的情况下,您的Visit方法将使用反射来“破解”传入的类型。

如何构建表达式树访问者有一个很好的example here,它正在做类似的事情(层次结构爬行)到​​你想要的东西。

答案 1 :(得分:1)

假设“入口点”位于层次结构的“顶部”(例如Class1Class2),我可以想到一些与建议的访客模式类似的扩展方法。

public static class FieldAndTypeExtensions {
    public static IEnumerable<FieldInfo> walk(this Type t) {
        foreach (FieldInfo f in t.GetFields()) {
            foreach (FieldInfo nextField in f.walk()) {
                yield return nextField;
            }
        }
    }
    public static IEnumerable<FieldInfo> walk(this FieldInfo f) {
        yield return f;
        FieldInfo[] fieldInfos = f.FieldType.GetFields();
        foreach (FieldInfo nextField in fieldInfos) {
            foreach (FieldInfo anotherNext in nextField.walk()) {
                yield return anotherNext;
            }
        }
    }
}

可能的用法是:

Type t = typeof(Class1);
var allFieldsFound = from field
                     in t.walk()
                     where field.FieldType == typeof(Class5)
                     select field;
var firstFound = allFieldsFound.FirstOrDefault();                        

firstFoundallFieldsFound中的条目都属于FieldInfo类型,因此您可以通过其DeclaringType属性获取声明(封闭)类。

也许这不是最优雅的解决方案,但也许是一个基础构思。