简体   繁体   English

如何在 LINQ 或其他方式中搜索树结构

[英]How can I search the tree structure in LINQ or some other way

public interface IComponent
{
    Guid Key { get; set; }
}
 public interface ICanHaveChildElement
{
    List<IComponent> ChildElement {get;set;}
}
public class BaseComponent : IComponent
{
    public Guid Key { get; set; }
}
public class TextBox : BaseComponent, IComponent
{

}
public class Radiobutton : BaseComponent, IComponent
{

}
public class Table : BaseComponent, IComponent, ICanHaveChildElement
{
    public List<IComponent> ChildElement { get; set; }
}
public class TestService
{
    public void Search(Guid key)
    {
        List<IComponent> components = new List<IComponent>();
        var element = components.FirstOrDefault(p => p.Key == key);
    }
}

Hello,你好,

When I search within the components (Textbox, Radio, etc.) that do not have subcomponents in my existing code block as above, I can find the component.当我在现有代码块中没有子组件的组件(文本框、收音机等)中进行搜索时,我可以找到该组件。 However, I cannot find components with subcomponents such as tables.但是,我找不到带有子组件(例如表)的组件。 I can find it by checking with if, but since I don't know how many sub-components it will have, it can only be successful in operations with one sub-element.我可以通过检查 if 找到它,但由于我不知道它有多少个子组件,所以它只能在一个子元素的操作中成功。

My question is "key" parameter I want to search the entire list.我的问题是我想搜索整个列表的“关键”参数。 I want to find even if the element with this key is a sub-element.即使具有此键的元素是子元素,我也想查找。

You can try something like this:你可以尝试这样的事情:

public IComponent Search(Guid key, IEnumerable<IComponent> components)
{
    foreach (var c in components)
    {
        if (c.Key == key)
        {
            return c;
        }
        else if (c is ICanHaveChildElement withChildren)
        {
            return Search(key, withChildren.ChildElement);
        }
    }

    return null;
}

The code checks in the loop if components key is equal to what you are looking for.代码在循环中检查 components 键是否等于您要查找的键。 If not, it checks if the component implements "has children" interface and if yes - processes its children recursively.如果没有,它检查组件是否实现了“有子级”接口,如果是 - 递归处理它的子级。

Please note that if you are using older versions of C#, pattern-matching statement in "else if" won't compile, but it can be easily replaced with "as" casting and checking on "not null".请注意,如果您使用的是旧版本的 C#,“else if”中的模式匹配语句将无法编译,但可以轻松地替换为“as”转换并检查“not null”。

public IComponent GetComponentByKey(Guid key, List<IComponent> components)
        {
            foreach (var c in components)
            {
                if (c.Key.Equals(key)) return c;
                else if (c is ICanHaveChildElement)
                {
                    return GetComponentByKey(key, (c as ICanHaveChildElement).ChildElement);
                }
            }
            return null;
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM