Как насчет:
var desiredNode = child.Ancestors().FirstOrDefault(node => node.Id == desiredId);
Это дает null
, если нужный узел не может быть найден.
РЕДАКТИРОВАТЬ: Хорошо, если вам нужна полная последовательность снизу вверх, вы можете просто использовать:
var nodes = child.Ancestors().TakeUntil(node => node.Id == desiredId);
, где TakeUntil
- это метод, подобный TakeWhile
, но включающий последний узел, который соответствует предикату.Вы можете найти пример реализации в MoreLINQ .Если вы не возражаете против отсутствия проверки аргументов (которую обеспечивает MoreLINQ ), написать очень просто:
public static IEnumerable<T> TakeUntil<T>(this IEnumerable<T> source,
Func<T, bool> predicate)
{
foreach (T item in source)
{
yield return item;
if (predicate(item))
{
yield break;
}
}
}
Вы могли бы создать функциональностьв метод Ancestors()
, но он объединяет две обязанности в одну относительно сложную функцию, вместо того, чтобы иметь две простые функции, которые могут быть составлены с другими простыми функциями очень общим способом.