75

I seem to be having some trouble wrapping my head around the idea of a Generic List of Generic Lists in C#. I think the problem stems form the use of the <T> argument, which I have no prior experience playing with. Could someone provide a short example of declaring a class which is a List, that therein contains another List, but where the type of the object contained therein is not immediately known?

I've been reading through the MS documentation on Generics, and I am not immediately sure if I can declare a List<List<T>>, nor how exactly to pass the <T> parameter to the inside list.

Edit: Adding information

Would declaring a List<List<T>> be considered legal here? In case you are wondering, I am building a class that allows me to use a ulong as the indexer, and (hopefully) steps around the nasty 2GB limit of .Net by maintaining a List of Lists.

public class DynamicList64<T>
    {
        private List<List<T>> data = new List<List<T>>();

        private ulong capacity = 0;
        private const int maxnumberOfItemsPerList = Int32.MaxValue;



        public DynamicList64()
        {
            data = new List<List<T>>();
        } 

7 Answers 7

135

A quick example:

List<List<string>> myList = new List<List<string>>();
myList.Add(new List<string> { "a", "b" });
myList.Add(new List<string> { "c", "d", "e" });
myList.Add(new List<string> { "qwerty", "asdf", "zxcv" });
myList.Add(new List<string> { "a", "b" });

// To iterate over it.
foreach (List<string> subList in myList)
{
    foreach (string item in subList)
    {
        Console.WriteLine(item);
    }
}

Is that what you were looking for? Or are you trying to create a new class that extends List<T> that has a member that is a `List'?

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

1 Comment

This answer just totally misses the point. OP wants to declare a List of Lists, where the inner lists are generic. Essentially, OP is looking for a List of variant litsts...
34

or this example, just to make it more visible:

public class CustomerListList : List<CustomerList> { }  

public class CustomerList : List<Customer> { }

public class Customer
{
   public int ID { get; set; }
   public string SomethingWithText { get; set; }
}

and you can keep it going. to the infinity and beyond !

4 Comments

+1. Good idea. You can even add customer specific stuff to it like an Add method taking a customer name as parameter, that creates and adds a customer automatically. (You need a where T : new() constraint for this).
You could just use alias' instead, since the body of the classes are all empty
@Servy, one up, I changed the post to make it as clear as possible to whoever sees it, tks
@ThePoet what lies beyond infinity?
7

A list of lists would essentially represent a tree structure, where each branch would constitute the same type as its parent, and its leaf nodes would represent values.

Implementation

public sealed class TreeList<T> : List<TreeList<T>>
{
    public List<T> Values { get; } = new List<T>();

    public TreeList<T> this[int index]
    {
        get
        {
            while (index > Count - 1)
            {
                Branch();
            }

            return base[index];
        }
    }

    public TreeList<T> Branch()
    {
        TreeList<T> result = new TreeList<T>();
        
        Add(result);

        return result;
    }
}

Example

internal static class Program
{
    public static void Main()
    {
        // Create the root element...
        TreeList<string> treeList = new TreeList<string>();
        
        // You can add branches the old-fashioned way...
        treeList.Add(new TreeList<string>());

        // Add leaf node values to your first branch...
        treeList[0].Values.Add("Hello, World!");
        treeList[0].Values.Add("Goodbye, World!");

        // You can create new branches from any branch like this...
        // Note: You could also chain branch statements; i.e. treeList.Branch().Branch().Branch()
        TreeList<string> branch2 = treeList.Branch();

        // Add leaf node values to your second branch...
        branch2.Values.Add("Alice");
        branch2.Values.Add("Bob");

        // You can also create branches until you reach the desired branch index...
        // The TreeList indexer will loop until the desired index has been created, and then return it.
        treeList[7].Values.Add("Alpha");
        treeList[7].Values.Add("Bravo");
        treeList[7].Values.Add("Charlie");

        // How many branches does the root have?
        Console.WriteLine($"Treelist branches: {treeList.Count}");

        // What's at branch 0's values?
        foreach (string value in treeList[0].Values)
        {
            Console.WriteLine(value);
        }

        // What's at branch 1's values?
        foreach (string value in treeList[1].Values)
        {
            Console.WriteLine(value);
        }

        // What's at branch 7's values?
        foreach (string value in treeList[7].Values)
        {
            Console.WriteLine(value);
        }
    }
}

Now, whether you should implement something like this is another matter. Extending List<T> isn't recommended: Why not inherit from List<T>?

Comments

3
public class ListOfLists<T> : List<List<T>>
{
}


var myList = new ListOfLists<string>();

1 Comment

Tested (I'm learning...) and this is the simplest actual answer to OP.
1

Look a direct example here:

public partial class Form1 : Form
{
    List<List<Label>> txtList;
    List<List<int>> num;
    public Form1()
    {
        InitializeComponent();
        txtList = new List< List<Label> >() { 
            new List<Label> { label1, label2, label3 }, 
            new List<Label> { label4, label5, label6 }, 
            new List<Label> { label7, label8, label9 } 
        };

        num = new List<List<int>>() { new List<int>() { 1, 2 }, new List<int>() { 3, 4 } };
    }
}

Comments

0

I have the following code

  public class ChildClass
    {
        public string FieldName { get; set; }
        public string Value { get; set; }
        public string StatusClass { get; set; }
        public string StatusMessage { get; set; }
    }

Creating a list of list obj is as follows

List<List<ChildClass>> obj = new List<List<ChildClass>>();

Comments

-3

you should not use Nested List in List.

List<List<T>> 

is not legal, even if T were a defined type.

https://msdn.microsoft.com/en-us/library/ms182144.aspx

1 Comment

What do you mean it's not legal? Of course it is. What you linked to is just a design warning. Such syntax is preferably avoided, particularly in public APIs but there are valid use cases for doing such things.

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.