使用Linq定位嵌套属性
本文关键字:属性 嵌套 定位 Linq 使用 | 更新日期: 2023-09-27 18:06:16
我有一个如下所示的对象模型。
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# .
假设"入口点"位于层次结构的"顶部"(例如Class1
或Class2
),我可以想到一些与建议的访问者模式类似的扩展方法。
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();
firstFound
和allFieldsFound
中的条目都是FieldInfo
类型的,因此您可以通过其DeclaringType
属性获得声明(封闭)类。
也许这不是最优雅的解决方案,但可能是一个基本的想法。
这样做的典型方法是使用Visitor模式。在你的例子中,你的Visit方法将使用反射来"打开"传入的类型。
这里有一个很好的例子,如何构造一个表达式树访问器,它做的事情与您想要的类似(层次结构爬行)。