2

I am trying to create a class that contains a list of "items" within it. Which I have successfully done, however then I would like to create a list of items within the list of items. I have also been able to do this however I had to use a different name for the class within the item.

I would like to use the same class name as this will be used to generate some json where the class name is important. In addition I would like to be able to do this in a way where it could be recursive like a folder structure. All the properties would be the same for each. I hope I am explaining this well enough. I am essentially trying to create a folder / file structure where there can be x number of files in each folder that can also have x number of folders and so forth.

For example:

DocLib

-Item

--Item.Items

---Item.Items.Items

--Item.Items

-Item 2 etc...

Here is the existing code:

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

I am sure there is probably a better way of implementing this.

2 Answers 2

6

Just let items be a list of your "own" type

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

EDIT usage sample:

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

    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

or have the item class contain a List<item> property
@ChrisDoggett yes this is exactly what I've done with a set of collection classes for representing AWS objects. The class can then be instantiated to represent either a single instance of the object or a collection of those objects.
You probably want to give the type a different name if you do this, as DocLib fails to be descriptive of what it does.
can you give a usage example on this...?
0

You could also do this with generics.

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

3 Comments

I tried to implement your structure, but getting an issue when adding new Items to the .lib.Items collection. Item is not assignable to type DocLib<Item> in the List<DocLib<Item>>.
@ElHaix Right you are... there were a few mistakes in that code that I have fixed. Primarily, each element in lib.Items should have been a DocLib<Item> which contains an Item, rather than just a collection of Item.
I started out working that path, but finished off a little differently. I created a public interface IItem with List<IItem> Items { get; set; } with some base properties. Then I created other item classes that inherit IItem. So Items can be stored within themselves.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.