如何处理作为参数传递到方法中的 Lambda 表达式 - C# .NET 3.5

发布于 2024-08-27 16:02:36 字数 1305 浏览 2 评论 0原文

我对 Lambda 表达式的了解有点不稳定,虽然我可以编写使用 Lambda 表达式(又名 LINQ)的代码,但我正在尝试编写自己的方法,该方法采用一些 Lambda 表达式类型的参数。

背景:我正在尝试编写一个方法,该方法从任何其他对象类型返回 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 原则)。

我以正确的方式处理这件事吗?也许有更好的方法吗?

My knowledge of Lambda expressions is a bit shaky, while I can write code that uses Lambda expressions (aka LINQ), I'm trying to write my own method that takes a few arguments that are of type Lambda Expression.

Background: I'm trying to write a method that returns a Tree Collection of objects of type TreeItem from literally ANY other object type. I have the following so far:

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;
    }
}

...which can be called via...

IList<TreeItem> treeItems = TreeItem.GetTreeFromObject<Category>(
    categories, c => c.Id, c => c.Name, c => c.ChildCategories);

I could replace the Expressions with string values, and just use reflection, but I'm trying to avoid this as I want to make it strongly typed.

My reasons for doing this is that I have a control that accepts a List of type TreeItem, whereas I have dozens of different types that are all in a tree like structure, and don't want to write seperate conversion methods for each type (trying to adhere to the DRY principle).

Am I going about this the right way? Is there a better way of doing this perhaps?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

失与倦" 2024-09-03 16:02:36

不存在“lambda 表达式”这样的类型。 lambda 表达式可以转换为兼容的委托类型,也可以转换为表达式树

您现有的方法签名使用表达式树 - 但根本不清楚它是否真的需要这样做。尝试委托形式(进行一些参数名称更改):

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
}

There's no such type as "lambda expression". A lambda expression can either be converted into a compatible delegate type, or an expression tree.

Your existing method signature uses expression trees - but it's not at all clear that it really needs to. Try the delegate form (with a few parameter name changes):

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

Then you can do something like this:

foreach (T item in items)
{
    string id = idSelector(item);
    string text = textSelector(item);
    IList<T> children = childPropertySelector(item);
    // Do whatever you need here
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文