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

Copy List sang List khác không dùng foreach trong C#

Nhiều cách copy List<T> mà không viết vòng lặp foreach thủ công.

Cách 1: Constructor List<T>(IEnumerable<T>) - Khuyến nghị nhất


List original = new List { 1, 2, 3, 4, 5 };
List copy = new List(original); // Shallow copy

// Hoặc từ bất kỳ IEnumerable nào
IEnumerable source = Enumerable.Range(1, 5);
List list = new List(source);

Cách 2: ToList() Extension Method


List copy = original.ToList(); // Tạo List mới từ IEnumerable

Cách 3: GetRange (Copy một đoạn)


// Copy từ index 0, lấy 3 phần tử
List partial = original.GetRange(0, 3); // {1, 2, 3}

// Copy toàn bộ
List full = original.GetRange(0, original.Count);

Cách 4: AddRange (Nối vào list hiện có)


List copy = new List();
copy.AddRange(original); // Thêm tất cả

Cách 5: Collection Expression (C# 12 / .NET 8+)


// C# 12: Collection expressions
List copy = [.. original]; // Spread operator
// Hoặc
int[] array = [.. original];

Shallow Copy vs Deep Copy

  • Tất cả cách trên là Shallow Copy: Copy reference cho reference type, copy giá trị cho value type.
  • Nếu T là class -> cả 2 list trỏ đến CÙNG object. Thay đổi property qua list 1 ảnh hưởng list 2.

Deep Copy cho Reference Type


public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    
    // Copy constructor
    public Person(Person other) { Name = other.Name; Age = other.Age; }
}

// Deep copy với Select + Constructor
List deepCopy = original.Select(p => new Person(p)).ToList();

// Hoặc serialize/deserialize (chậm, nhưng generic)
string json = JsonConvert.SerializeObject(original);
List deepCopy2 = JsonConvert.DeserializeObject>(json);

So sánh hiệu suất (1M elements)

Phương phápThời gian (ms)Allocation
new List(original)~151 array
original.ToList()~151 array
original.GetRange(0, Count)~121 array (fastest)
new List(); copy.AddRange(original)~181 array + list overhead
[.. original] (C# 12)~151 array

Khi nào dùng cái nào?

  • new List(original) / ToList(): General purpose, readable.
  • GetRange: Cần subset hoặc muốn nhanh nhất cho full copy.
  • AddRange: Nối vào list đã tồn tại.
  • Select(p => new T(p)).ToList(): Deep copy cho reference types.