Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

วิธีเก็บ List หลายประเภทใน Generic List เดียวใน C#

วิธีการ: ใช้ List<List<object>>

เนื่องจาก object เป็น Base Type ของทุก Type จึงสามารถเก็บ List ของ Type ใดๆ ได้

Syntax


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

ตัวอย่างโค้ด


using System;
using System.Collections.Generic;

namespace MyApplication
{
    public class Program
    {
        public static void Main()
        {
            // Container: List of List
            List<List<object>> masterList = new List<List<object>>();
            
            // List 1: Integers
            List<object> intList = new List<object>();
            intList.Add(101);
            intList.Add(102);
            intList.Add(103);
            masterList.Add(intList);
            
            // List 2: Strings
            List<object> stringList = new List<object>();
            stringList.Add("Test1");
            stringList.Add("Test2");
            stringList.Add("Test3");
            masterList.Add(stringList);
            
            // List 3: Mixed Types (Object จริงๆ)
            List<object> mixedList = new List<object>();
            mixedList.Add(42);
            mixedList.Add("Hello");
            mixedList.Add(DateTime.Now);
            mixedList.Add(new { Id = 1, Name = "Anonymous" });
            masterList.Add(mixedList);
            
            // Iterate และแสดงผล
            foreach (List<object> subList in masterList)
            {
                Console.WriteLine($"--- SubList (Count: {subList.Count}) ---");
                foreach (object obj in subList)
                {
                    Console.WriteLine($"  {obj?.GetType().Name}: {obj}");
                }
                Console.WriteLine();
            }
            
            Console.ReadLine();
        }
    }
}


Output

--- SubList (Count: 3) ---
  Int32: 101
  Int32: 102
  Int32: 103

--- SubList (Count: 3) ---
  String: Test1
  String: Test2
  String: Test3

--- SubList (Count: 4) ---
  Int32: 42
  String: Hello
  DateTime: 1/1/2024 10:30:00 AM
  AnonymousType: { Id = 1, Name = Anonymous }

Alternative Approaches (ที่ดีกว่าสำหรับ Production)

1. List<object> แบบ Flat (Single List)


List<object> items = new List<object>();
items.Add(101);
items.Add("Hello");
items.Add(new Person { Name = "John" });

2. Tuple List (Named, Type-Safe)


// C# 7+ ValueTuple
var data = new List<(string Type, object Value)>();
data.Add(("Int", 101));
data.Add(("String", "Hello"));
data.Add(("Person", new Person { Name = "John" }));

3. Base Class / Interface (Polymorphism)


interface IEntity { int Id { get; } }
class User : IEntity { public int Id { get; set; } public string Name { get; set; } }
class Product : IEntity { public int Id { get; set; } public decimal Price { get; set; } }

List<IEntity> entities = new List<IEntity>();
entities.Add(new User { Id = 1, Name = "John" });
entities.Add(new Product { Id = 2, Price = 99.99m });

4. Discriminated Union / OneOf (Library)


// Using OneOf Library
using OneOf;

OneOf<int, string, Person> value = 42;
OneOf<int, string, Person> value2 = "Hello";
OneOf<int, string, Person> value3 = new Person { Name = "John" };

// Pattern Matching
string result = value.Match(
    i => $"Int: {i}",
    s => $"String: {s}",
    p => $"Person: {p.Name}"
);

ข้อควรระวังกับ List<List<object>>

⚠️ Boxing/Unboxing Overhead
- Value Types (int, double, struct) ต้อง Boxing → Heap Allocation
- Unboxing ตอนอ่าน ค่อนข้างช้า
- ใช้สำหรับ Prototype/Demo/Scripting เท่านั้น
- Production ควรใช้ Polymorphism (Interface/Base Class) หรือ Generic

Generic Alternative (Type-Safe)


// Wrapper Class
public class TypedList<T>
{
    public List<T> Items { get; } = new List<T>();
    public string TypeName => typeof(T).Name;
}

// Usage
var lists = new List<object> 
{ 
    new TypedList<int> { Items = { 1, 2, 3 } },
    new TypedList<string> { Items = { "A", "B" } }
};