How to store n number of lists of different types in a single generic list in C#?

We can store n number of lists of different types in a single generic list by creating a list of List<object>. This approach allows us to store lists containing integers, strings, or any other data type within a single container.

Syntax

Following is the syntax for creating a list that can hold multiple lists of different types −

List<List<object>> containerList = new List<List<object>>();

Each inner list can store objects of any type −

List<object> innerList = new List<object>();
innerList.Add(value); // value can be int, string, etc.
containerList.Add(innerList);

Using List of List<object>

The most straightforward approach is to use List<object> for each inner list, allowing them to store any data type −

Example

using System;
using System.Collections.Generic;

namespace MyApplication {
    public class Program {
        public static void Main() {
            List<List<object>> list = new List<List<object>>();
            
            List<object> list1 = new List<object>();
            list1.Add(101);
            list1.Add(102);
            list1.Add(103);
            list.Add(list1);
            
            List<object> list2 = new List<object>();
            list2.Add("Test1");
            list2.Add("Test2");
            list2.Add("Test3");
            list.Add(list2);
            
            foreach (List<object> objectList in list) {
                foreach (object obj in objectList) {
                    Console.WriteLine(obj);
                }
                Console.WriteLine();
            }
        }
    }
}

The output of the above code is −

101
102
103

Test1
Test2
Test3

Using Generic Container with Dynamic

Another approach is to use dynamic type, which provides more flexibility at runtime −

Example

using System;
using System.Collections.Generic;

namespace MyApplication {
    public class Program {
        public static void Main() {
            List<dynamic> containerList = new List<dynamic>();
            
            List<int> intList = new List<int> { 10, 20, 30 };
            List<string> stringList = new List<string> { "Apple", "Banana", "Cherry" };
            List<double> doubleList = new List<double> { 1.5, 2.7, 3.9 };
            
            containerList.Add(intList);
            containerList.Add(stringList);
            containerList.Add(doubleList);
            
            foreach (var list in containerList) {
                Console.WriteLine($"List type: {list.GetType().Name}");
                foreach (var item in list) {
                    Console.WriteLine($"  {item}");
                }
                Console.WriteLine();
            }
        }
    }
}

The output of the above code is −

List type: List`1
  10
  20
  30

List type: List`1
  Apple
  Banana
  Cherry

List type: List`1
  1.5
  2.7
  3.9

Using Collections with Type Information

For better type safety and identification, you can store lists along with their type information −

Example

using System;
using System.Collections.Generic;

namespace MyApplication {
    public class TypedList {
        public string TypeName { get; set; }
        public List<object> Items { get; set; }
        
        public TypedList(string typeName) {
            TypeName = typeName;
            Items = new List<object>();
        }
    }
    
    public class Program {
        public static void Main() {
            List<TypedList> typedLists = new List<TypedList>();
            
            TypedList integerList = new TypedList("Integer");
            integerList.Items.AddRange(new object[] { 5, 15, 25 });
            
            TypedList stringList = new TypedList("String");
            stringList.Items.AddRange(new object[] { "Red", "Green", "Blue" });
            
            typedLists.Add(integerList);
            typedLists.Add(stringList);
            
            foreach (var typedList in typedLists) {
                Console.WriteLine($"Type: {typedList.TypeName}");
                foreach (var item in typedList.Items) {
                    Console.WriteLine($"  {item}");
                }
                Console.WriteLine();
            }
        }
    }
}

The output of the above code is −

Type: Integer
  5
  15
  25

Type: String
  Red
  Green
  Blue

Comparison of Approaches

Approach Pros Cons
List<List<object>> Simple, straightforward Boxing/unboxing for value types, no compile-time type checking
List<dynamic> Preserves original list types, runtime flexibility No compile-time type checking, potential runtime errors
Custom TypedList Type information preserved, better organization More complex, requires additional wrapper class

Conclusion

Storing multiple lists of different types can be achieved using List<List<object>>, List<dynamic>, or custom wrapper classes. The List<object> approach is most common for simple scenarios, while custom wrappers provide better type organization and identification.

Updated on: 2026-03-17T07:04:36+05:30

869 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements