Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Lưu nhiều List kiểu khác nhau vào một List chung trong C#

Vấn đề

C# là strongly-typed. List<T> chỉ chứa một kiểu T. Để lưu nhiều list kiểu khác nhau, cần một kiểu chung (common base).

Giải pháp 1: List<List<object>> (Đơn giản nhất)


using System;
using System.Collections.Generic;

class Program 
{
    static void Main() 
    {
        // List chứa các List
        var lists = new List>();
        
        // List 1: int
        var intList = new List { 101, 102, 103 };
        lists.Add(intList);
        
        // List 2: string
        var stringList = new List { "Test1", "Test2", "Test3" };
        lists.Add(stringList);
        
        // List 3: mixed types
        var mixedList = new List { 1, "Two", 3.0, DateTime.Now };
        lists.Add(mixedList);
        
        // Duyệt và in
        foreach (var list in lists) 
        {
            foreach (var item in list) 
            {
                Console.WriteLine($"{item.GetType().Name}: {item}");
            }
            Console.WriteLine("---");
        }
    }
}


Giải pháp 2: Interface/Base Class chung (Type-safe hơn)


// Base interface
public interface IEntity 
{
    int Id { get; }
    string DisplayName { get; }
}

public class User : IEntity 
{
    public int Id { get; set; }
    public string Username { get; set; }
    public string DisplayName => Username;
}

public class Product : IEntity 
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string DisplayName => Name;
}

// Sử dụng
var entities = new List>();

var users = new List 
{
    new User { Id = 1, Username = "john" },
    new User { Id = 2, Username = "jane" }
};

var products = new List 
{
    new Product { Id = 100, Name = "Laptop" },
    new Product { Id = 200, Name = "Mouse" }
};

entities.Add(users);
entities.Add(products);

// Type-safe access
foreach (var list in entities) 
{
    foreach (var entity in list) 
    {
        Console.WriteLine($"ID: {entity.Id}, Name: {entity.DisplayName}");
    }
}

Giải pháp 3: Tuple/List of Tuples (C# 7+)


// Tuple với named elements
var data = new List<(string Type, List Items)>
{
    ("Integers", new List { 1, 2, 3 }),
    ("Strings", new List { "A", "B", "C" }),
    ("Mixed", new List { 1, "Two", 3.0 })
};

foreach (var (type, items) in data) 
{
    Console.WriteLine($"--- {type} ---");
    foreach (var item in items) Console.WriteLine(item);
}


Giải pháp 4: Dictionary với Key phân loại


// Dictionary> - group by type
var dict = new Dictionary>();

void Add(List list) where T : class 
{
    dict[typeof(T)] = list.Cast().ToList();
}

Add(new List { 1, 2, 3 });
Add(new List { "A", "B" });

// Truy xuất
if (dict.TryGetValue(typeof(int), out var ints)) 
{
    foreach (var i in ints) Console.WriteLine(i);
}


Giải pháp 5: Pattern Matching khi đọc (C# 7+)


var lists = new List> 
{
    new List { 1, 2, 3 },
    new List { "A", "B" },
    new List { 1.5, 2.5 }
};

foreach (var list in lists) 
{
    foreach (var item in list) 
    {
        switch (item) 
        {
            case int i: Console.WriteLine($"Int: {i}"); break;
            case string s: Console.WriteLine($"String: {s}"); break;
            case double d: Console.WriteLine($"Double: {d}"); break;
            default: Console.WriteLine($"Other: {item}"); break;
        }
    }
}


So sánh các giải pháp

Giải phápType SafetyPerformancePhức tạpUse Case
List<List<object>>Thấp (boxing/unboxing)Trung bìnhThấpQuick prototype, throwaway code
List<List<IInterface>>CaoTốtTrung bìnhDomain model có interface chung
List<(Type, List)>Trung bìnhTốtThấpCần metadata về loại list
Dictionary<Type, List>Cao (key là Type)TốtTrung bìnhTra cứu nhanh theo kiểu

⚠️ Lưu ý quan trọng

Boxing/Unboxing cost: Khi dùng object với value types (int, double, struct) → boxing alloc heap, unboxing copy back. Với dữ liệu lớn/high-frequency → dùng generic interface hoặc custom solution.

Alternative: Non-generic IList (Legacy)


// Non-generic IList - chỉ dùng cho legacy COM/interop
System.Collections.IList list = new ArrayList();
list.Add(1);
list.Add("string");
// Không type-safe, boxing mọi value type - KHÔNG KHUYẾN NGHỊ