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

Tạo shallow copy của ArrayList trong C#

Khái niệm

Shallow copy** (bản sao nông) tạo một ArrayList mới chứa **tham chiếu** đến cùng các đối tượng với ArrayList gốc. Thay đổi đối tượng con (nếu là reference type) sẽ ảnh hưởng cả hai. Đối với kiểu giá trị (int, string...) thì an toàn vì immutable.

Phương thức: Clone()

ArrayList cloned = (ArrayList)original.Clone();

Ví dụ 1: Shallow copy cơ bản

using System;
using System.Collections;

public class Demo
{
    public static void Main()
    {
        ArrayList list = new ArrayList();
        list.Add("One");
        list.Add("Two");
        list.Add("Three");
        list.Add("Four");
        list.Add("Five");
        list.Add("Six");
        list.Add("Seven");
        list.Add("Eight");

        Console.WriteLine("ArrayList gốc:");
        foreach (string s in list) Console.WriteLine(s);

        list.Insert(4, "Twelve"); // Chèn tại index 4

        Console.WriteLine("\nArrayList gốc sau Insert:");
        foreach (string s in list) Console.WriteLine(s);

        // Shallow copy
        ArrayList list2 = (ArrayList)list.Clone();

        Console.WriteLine("\nCloned ArrayList:");
        foreach (string s in list2) Console.WriteLine(s);
    }
}

Kết quả

ArrayList gốc:
One
Two
Three
Four
Five
Six
Seven
Eight

ArrayList gốc sau Insert:
One
Two
Three
Four
Twelve
Five
Six
Seven
Eight

Cloned ArrayList:
One
Two
Three
Four
Twelve
Five
Six
Seven
Eight

Ví dụ 2: Clone sau khi Remove

using System;
using System.Collections;

public class Demo
{
    public static void Main(string[] args)
    {
        ArrayList list1 = new ArrayList();
        list1.Add("A"); list1.Add("B"); list1.Add("C"); list1.Add("D");
        list1.Add("E"); list1.Add("F"); list1.Add("G"); list1.Add("H"); list1.Add("I");

        ArrayList list2 = new ArrayList();
        list2.Add("A"); list2.Add("B"); list2.Add("C"); list2.Add("D");
        list2.Add("E"); list2.Add("F"); list2.Add("G"); list2.Add("H"); list2.Add("I");
        list2.Add("G"); list2.Add("I"); // Duplicate

        Console.WriteLine($"List2 Count: {list2.Count}"); // 11

        list2.Remove("G"); // Xóa lần đầu "G"
        Console.WriteLine($"List2 Count sau Remove: {list2.Count}"); // 10

        ArrayList list3 = (ArrayList)list2.Clone();

        Console.WriteLine("\nCloned từ List2:");
        foreach (string s in list3) Console.WriteLine(s);
    }
}

Kết quả

List2 Count: 11
List2 Count sau Remove: 10

Cloned từ List2:
A
B
C
D
E
F
H
I
G
I

Shallow vs Deep Copy

LoạiArrayList.Clone()Deep Copy (tự cài)
Kiểu giá trị (int, string, struct)An toàn (copy giá trị)An toàn
Reference type (class, array, object[])Chia sẻ referenceTạo object mới đệ quy
Hiệu năngNhanh, O(n)Chậm, O(n) + overhead

Khi nào cần Deep Copy?

ArrayList original = new ArrayList();
original.Add(new int[] {1, 2}); // Reference type
original.Add("hello");          // Immutable

ArrayList shallow = (ArrayList)original.Clone();

// Thay đổi mảng con -> ảnh hưởng cả hai
((int[])shallow[0])[0] = 99;
Console.WriteLine(((int[])original[0])[0]); // 99 !!

Giải pháp deep copy: Serialize/Deserialize (JSON, BinaryFormatter), hoặc dùng thư viện (AutoMapper, Newtonsoft.Json), hoặc tự viết recursive copy.

Lưu ý

  • ArrayList là non-generic, khuyến nghị dùng List<T>. List<T> không có Clone(), dùng new List<T>(oldList) (shallow copy).
  • Shallow copy đủ cho kiểu giá trị và string.