【问题标题】:Finding the root nodes of all the of a tree from a nodes in any generic list从任何通用列表中的节点中查找所有树的根节点
【发布时间】:2012-06-19 12:33:06
【问题描述】:

这是一个实体,我想在通用函数中列出给定节点的所有子节点

    public static List<T> BuildTree<T>(List<T> list, T selectNode string keyPropName, string parentPropName, string levelPropName, int level = 0)
    {
        List<T> entity = new List<T>();

        foreach (T item in list)
        {


        }


        return entity;
    }

实体结构示例

    protected long _coakey;
    protected long _parentkey;
    protected string _coacode;
    protected string _coacodeclient;
    protected string _coaname;
    protected int _coalevel;

    [DataMember]
    public long coakey
    {
        get { return _coakey; }
        set { _coakey = value; this.OnChnaged(); }
    }

    [DataMember]
    public long parentkey
    {
        get { return _parentkey; }
        set { _parentkey = value; this.OnChnaged(); }
    }

    [DataMember]
    public string coacode
    {
        get { return _coacode; }
        set { _coacode = value; this.OnChnaged(); }
    }

    [DataMember]
    public string coacodeclient
    {
        get { return _coacodeclient; }
        set { _coacodeclient = value; this.OnChnaged(); }
    }

    [DataMember]
    public string coaname
    {
        get { return _coaname; }
        set { _coaname = value; this.OnChnaged(); }
    }

    [DataMember]
    public int coalevel
    {
        get { return _coalevel; }
        set { _coalevel = value; this.OnChnaged(); }
    }

【问题讨论】:

  • 我完全不清楚你想要达到什么目的......
  • 您不能真正将树返回为 List...无论如何,对于动态属性访问等,请参阅 Reflection

标签: c# search tree


【解决方案1】:

你的BuildTree&lt;T&gt; 方法不能确定树的结构,除非它知道一些关于它的结构。至少,我建议创建一个定义树节点的基类或接口,然后更改 BuildTree 方法以专门处理这些类型的对象。然后,它将能够找出树结构。你们每个实体类都必须实现该树节点接口或从树节点基类继承。例如:

public abstract class TreeNodeBase
{
    public long parentkey
    {
        get { return _parentkey; }
        set { _parentkey = value; this.OnChanged(); }
    }
    protected long _parentkey;
}

public class MyEntityTreeNode : TreeNodeBase
{
    public long coakey
    {
        get { return _coakey; }
        set { _coakey = value; this.OnChanged(); }
    }
    protected long _coakey;

    // etc...
}

// Note the generic type constraint at the end of the next line
public static List<T> BuildTree<T>(List<T> list, T selectNode, string keyPropName, string parentPropName, string levelPropName, int level) where T : TreeNodeBase
{
    List<T> entity = new List<T>();
    foreach (TreeNodeBase node in list)
    {
        long parentKey = node.parentkey;
        // etc...
    }
    return entity;
}

【讨论】:

    【解决方案2】:

    节点类:

    public class Node<TKey, TValue> where TKey : IEquatable<TKey>
    {
        public TKey Key { get; set; }
        public TKey ParentKey { get; set; }
        public TValue Data { get; set; }
    
        public readonly List<Node<TKey, TValue>> Children = new List<Node<TKey, TValue>>();
    }
    

    TreeBuilder:

    public static Node<TKey, TValue> BuildTree<TKey, TValue>(IEnumerable<Node<TKey, TValue>> list,
                                                             Node<TKey, TValue> selectNode)
        where TKey : IEquatable<TKey>
    {
        if (ReferenceEquals(selectNode, null))
        {
            return null;
        }
    
        var selectNodeKey = selectNode.Key;
    
        foreach (var childNode in list.Where(x => x.ParentKey.Equals(selectNodeKey)))
        {
            selectNode.Children.Add(BuildTree(list, childNode));
        }
    
        return selectNode;
    }
    

    用法:

    List<MyClass> list = ...
    
    var nodes = list.Select(x => new Node<long, MyClass>
                                     {
                                         Key = x.MyKey,
                                         ParentKey = x.MyParentKey,
                                         Data = x
                                     }).ToList();
    
    var startNode = nodes.FirstOrDefault(x => x.Data.Stuff == "Pick me!");
    
    var tree = BuildTree(nodes, startNode);
    

    MyClass 示例:

    public class MyClass
    {
        public long MyKey;
        public long MyParentKey;
        public string Name;
        public string Text;
        public string Stuff;
    }
    

    【讨论】:

      【解决方案3】:

      我自己解决了希望对你有帮助

          public static List<T> BuildTree<T>(List<T> list, T selectedNode, string keyPropName, string parentPropName, int endLevel = 0, int level = 0)
          {
              List<T> entity = new List<T>();
              Type type = typeof(T);
              PropertyInfo keyProp = type.GetProperty(keyPropName);
              string _selectedNodekey = keyProp.GetValue(selectedNode, null).ToString();
      
              PropertyInfo parentProp = type.GetProperty(parentPropName);
              foreach (T item in list)
              {
      
                  string _key = keyProp.GetValue(item, null).ToString();
                  string _parent = parentProp.GetValue(item, null).ToString();
      
                  if (_selectedNodekey == _parent)
                  {
                      T obj = (T)Activator.CreateInstance(typeof(T));
                      obj = item;
                      entity.Add(obj);
                      if (level == endLevel && level!=0) break;
                      entity.AddRange(BuildTree<T>(list, obj, keyPropName, parentPropName, level + 1));
                  }
              }
      
      
              return entity;
      
          }
      

      【讨论】:

      • 你打电话给GetProperty(keyPropName) 两次没用。另外,将这些调用移到循环之外,因为一遍又一遍地调用它们是一种浪费。其次,将树表示为列表是我见过的最丑陋的东西之一,没有冒犯。
      • 我需要一个组合列表,所以我需要使用一个列表...感谢您的建议
      • selectedNodeKeyPropkeyProp 仍然完全相同。失去其中一个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多