Мое знание Лямбда-выражений немного шатко, в то время как я могу написать код, который использует Лямбда-выражения (иначе LINQ), я пытаюсь записать свой собственный метод, который берет несколько аргументов, которые имеют Лямбда-выражение типа.
Фон: я пытаюсь записать метод, который возвращает Древовидный Набор объектов типа TreeItem от буквально Любого другого типа объекта. У меня есть следующее до сих пор:
public class TreeItem
{
public string Id { get; set; }
public string Text { get; set; }
public TreeItem Parent { get; protected set; }
public IList<TreeItem> Children
{
get
{
// Implementation that returns custom TreeItemCollection type
}
}
public static IList<TreeItem> GetTreeFromObject<T>(IList<T> items,
Expression<Func<T, string>> id,
Expression<Func<T, string>> text,
Expression<Func<T, IList<T>>> childProperty) where T : class
{
foreach (T item in items)
{
// Errrm!?? What do I do now?
}
return null;
}
}
... через который можно назвать...
IList<TreeItem> treeItems = TreeItem.GetTreeFromObject<Category>(
categories, c => c.Id, c => c.Name, c => c.ChildCategories);
Я мог заменить Выражения строковыми значениями и просто использовать отражение, но я стараюсь избегать этого, поскольку я хочу сделать его со строгим контролем типов.
Мои причины того, чтобы сделать это - то, что я имею контроль, который принимает Список типа TreeItem, тогда как у меня есть десятки различных типов, которые являются всеми в дереве как структура и не хотят писать отдельные методы преобразования для каждого типа (пытающийся придерживаться принципа DRY).
Я иду об этом правильным путем? Существует ли лучший способ сделать это, возможно?
Не существует такого типа, как «лямбда-выражение». Лямбда-выражение может быть преобразовано либо в совместимый тип делегата, либо в дерево выражений .
В вашей существующей сигнатуре метода используются деревья выражений, но не совсем ясно, действительно ли это необходимо. Попробуйте использовать форму делегата (с несколькими изменениями имени параметра):
public static IList<TreeItem> GetTreeFromObject<T>(IList<T> items,
Func<T, string> idSelector,
Func<T, string> textSelector,
Func<T, IList<T>> childPropertySelector) where T : class
Затем вы можете сделать что-то вроде этого:
foreach (T item in items)
{
string id = idSelector(item);
string text = textSelector(item);
IList<T> children = childPropertySelector(item);
// Do whatever you need here
}