【问题标题】:C# Class with recursion带递归的 C# 类
【发布时间】:2012-12-28 18:35:40
【问题描述】:

我正在尝试创建一个包含“项目”列表的类。我已经成功完成了,但是我想在项目列表中创建一个项目列表。我也能够做到这一点,但是我必须为项目中的类使用不同的名称。

我想使用相同的类名,因为这将用于生成一些类名很重要的 json。此外,我希望能够以一种可以像文件夹结构一样递归的方式来做到这一点。每个属性的所有属性都是相同的。我希望我能很好地解释这一点。我实际上是在尝试创建一个文件夹/文件结构,其中每个文件夹中可以有 x 个文件,也可以有 x 个文件夹等等。

例如:

文档库

-物品

--Item.Items

---Item.Items.Items

--Item.Items

-第 2 项等...

这是现有的代码:

public class DocLib
{
    public string Title { get; set; }
    public string spriteCssClass { get { return "rootfolder"; } }
    public List<item> items { get; set; }

    public DocLib()
    {
        items = new List<item>();
    }

    public class item
    {
        public string Title { get; set; }
        public string spriteCssClass { get; set; }
        public List<document> documents { get; set; }

        public item()
        {
            documents = new List<document>();
        }

        public class document
        {
            public string Title { get; set; }
            public string spriteCssClass { get; set; }
        }
    }
}

我确信可能有更好的方法来实现这一点。

【问题讨论】:

    标签: c# list class recursion


    【解决方案1】:

    让 items 成为你“自己”类型的列表

    public class DocLib{
       public string Title { get; set; }
       public string spriteCssClass { get { return "rootfolder"; } }
    
       List<DocLib> _items;
    
       public DocLib(){
          _items = new List<DocLib>();
       }
    
       public List<DocLib> Items { 
          get{
             return _items;
          }
       }
    }
    

    编辑使用示例:

    public static class DocLibExtensions {
        public static void Traverse(this DocLib lib,Action<DocLib> process) {
            foreach (var item in lib.Items) {
                process(item);
                item.Traverse(process);
            }
        }
    }
    
    class Program {
        static void Main(string[] args) {
    
            DocLib rootDoc = new DocLib {Title = "root"};
    
            rootDoc.Items.Add( new DocLib{ Title = "c1" });
            rootDoc.Items.Add(new DocLib { Title = "c2" });
    
            DocLib child = new DocLib {Title = "c3"};
            child.Items.Add(new DocLib {Title = "c3.1"});
    
            rootDoc.Items.Add(child);
    
            rootDoc.Traverse(i => Console.WriteLine(i.Title));
    
        }
    }
    

    【讨论】:

    • 或让项目类包含 List 属性
    • @ChrisDoggett 是的,这正是我使用一组表示 AWS 对象的集合类所做的。然后可以实例化该类以表示对象的单个实例或这些对象的集合。
    • 如果你这样做,你可能想给类型一个不同的名字,因为DocLib 无法描述它的作用。
    • 你能举个例子吗?
    【解决方案2】:

    您也可以使用泛型来做到这一点。

    public class DocLib<T>
    {
       public T Item { get; set; }
       public IEnumerable<DocLib<T>> Items { get; set; }
    }
    
    public class Item
    {
       public string Title { get; set; }
       public string spriteCssClass { get; set; }
    }
    
    //Usage
    //Set up a root item, and some sub-items
    var lib  = new DocLib<Item>();
    lib.Item = new Item { Title="ABC", spriteCssClass="DEF" };
    lib.Items = new List<DocLib<Item>> { 
      new DocLib<Item>{ Item = new Item {Title="ABC2", spriteCssClass="DEF2"} },
      new DocLib<Item>{ Item = new Item {Title="ABC3", spriteCssClass="DEF3"} }
    };
    
    //Get the values
    var root = lib.Item;
    var subItems = lib.Items.Select(i=>i.Item);
    

    【讨论】:

    • 我尝试实现您的结构,但在将新项目添加到 .lib.Items 集合时遇到问题。项目不可分配给 List> 中的类型 DocLib
    • @ElHaix 是的……我已经修复了该代码中的一些错误。首先,lib.Items 中的每个元素都应该是一个DocLibItem>,其中包含一个Item,而不仅仅是Item 的集合。
    • 我开始走这条路,但完成的有点不同。我用List&lt;IItem&gt; Items { get; set; } 创建了一个public interface IItem 和一些基本属性。然后我创建了其他继承IItem 的项目类。所以Items可以自己存储。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多