我正在尝试在复杂对象中查找值。有没有人知道是否有一个助手类已经这样做了?
希望能够搜索一个对象,同时观察无限循环保护,找到包含“foo”的tostring值,然后返回找到foo的属性路径。或者找到一个路径foo数组。
所以如果有人在我自己承担这个代码之前有现有的代码;我将非常感激。
答案 0 :(得分:1)
关键是你想要在递归搜索你所追求的值以及Stack
个被访问对象时跳过当前属性的HashSet
并跳过它们。您还需要小心处理异常处理,因此中间的异常不会弄乱堆栈。
public static string[] FindPathToProperty(object item, string propertyValueToFind)
{
var pathToProperty = new Stack<string>();
var visitedObjects = new HashSet<object> {item};
FindPathToProperty(item, propertyValueToFind, pathToProperty, visitedObjects);
var finalPath = pathToProperty.ToArray();
Array.Reverse(finalPath);
return finalPath;
}
private static bool FindPathToProperty(object item, string propertyValueToFind, Stack<string> pathToProperty, HashSet<object> visitedObjects)
{
foreach (var property in item.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
try
{
var value = property.GetValue(item, null);
if (visitedObjects.Contains(value))
{
continue;
}
visitedObjects.Add(value);
pathToProperty.Push(property.Name);
bool found = false;
try
{
found = propertyValueToFind.Equals(value) ||
FindPathToProperty(value, propertyValueToFind, pathToProperty, visitedObjects);
}
finally
{
if (!found)
{
pathToProperty.Pop();
}
}
if (found)
{
return true;
}
}
catch
{
continue;
}
}
return false;
}
public static void Test()
{
Test(new { X = "find" }, "X");
Test(new { X = "no", Y = "find" }, "Y");
Test(new { A = new { X = "no", Y = "find" } }, "A.Y");
}
private static void Test(object item, string expected)
{
string actual = string.Join(".", FindPathToProperty(item, "find"));
Console.WriteLine("{0} : {1}\r\n {2}",
actual == expected ? "ok " : "BAD",
expected,
actual);
}