2012-05-24 21 views
6

Tôi đang chuyển danh sách loại gấp đôi [] đến hàm trong lớp, chỉnh sửa giá trị trong hàm bằng cách sử dụng tempList, sau đó trả về giá trị đã chỉnh sửa. Nhưng danh sách ban đầu đang được chuyển cũng đang được chỉnh sửa mà tôi không muốn chúng được chỉnh sửa để khớp với tempList.Vấn đề với danh sách chỉnh sửa <double[]> trong C#

Đây là mã.

List<double[]> newList = new List<double[](); 
newList = myClass.myFunction(value, originalList); 

// myClass 
... 

// myFunction 
public List<double[]> myFunction(int value, List<double[]> myList) 
{ 
    List<double[]> tempList = new List<double[]>(); 
    for (int i = 0; i < myList).Count; i++) 
    { 
     tempList.Add(myList[i]); 
    } 


    // Do stuff to edit tempList 

    return tempList; 
} 
+0

Điều gì thực sự là câu hỏi của bạn, những gì bạn muốn làm gì? Bạn có thể chỉnh sửa danh sách gốc , bạn không cần phải tạo một danh sách mới. –

Trả lời

4

Gấu nhớ rằng mảng là tham khảo loại. Khi bạn thêm mảng vào tempList, chỉ một tham chiếu đến mảng mới được thêm vào, do đó, myListtempList đều tham chiếu đến cùng một đối tượng double[].

Thay vào đó, bạn cần phải thực hiện một bản sao của các mảng:

for (int i = 0; i < myList.Count; i++) 
{ 
    tempList.Add((double[])myList[i].Clone()); 
} 
+0

Có, nhưng mã có vẻ tinh ranh ngay từ đầu. Nhân bản một mảng hiếm khi là điều đúng đắn cần làm. –

0

Vấn đề bạn đang gặp là double[] là một loại tài liệu tham khảo, không phải là một kiểu giá trị, vì vậy khi bạn đang thêm nó vào tempList của bạn, bạn đang thêm một tham chiếu đến đối tượng gốc, không phải là một đối tượng mới. Bạn thực sự cần phải tạo một double[] mới trước khi thêm nó vào tempList để bạn không làm việc trên đối tượng gốc.

Giả sử bạn có thể sử dụng LINQ, bạn không cần lặp lại. Bạn có thể làm điều gì đó như:

var tempList = myList.Select(x => x.ToArray()).ToList(); 
0

Điều này là do Bộ sưu tập/loại tham chiếu được chuyển qua tham chiếu. (Trên thực tế biến giữ được truyền theo giá trị, nhưng tất cả các biến trỏ đến cùng một tham chiếu).

Đối với chi tiết giải thích, đọc this SO Answer

Nếu bạn muốn rằng những sửa đổi trong chức năng của tôi không phản ánh trong bộ sưu tập ban đầu, bạn phải sao chép/sao chép nó và sau đó vượt qua để myFunction.

Ví dụ

newList = myClass.myFunction(value, (List<double>)originalList.Clone()); 
1

Một mảng, here double[], là một loại tài liệu tham khảo, vì vậy dòng

tempList.Add(myList[i]); 

là thêm một tham chiếu đến các mảng ban đầu. Sau đó, khi bạn chỉnh sửa tempList bạn đang chỉnh sửa mảng ban đầu. Tạo một bản sao như thế này:

tempList.Add(myList[i].ToArray()); 
0
tempList.Add(myList[i]); 

có nghĩa rằng bạn thêm tham chiếu đến [] đối tượng đúp vào chỉ số i vào danh sách tạm thời. do đó, nếu bạn chỉnh sửa giá trị của đối tượng đó, bạn sẽ có cơ hội trên cả hai danh sách.

nếu bạn muốn có một danh sách nhân bản khác nhau mà sẽ không ảnh hưởng lẫn nhau bạn sẽ phải làm điều đó:

List<double[]> tempList = new List<double[]>(); 
for (int i = 0; i < myList).Count; i++) 
{ 
    double[] originalListItem = myList[i]; 

    // the most important step here!!! - clone the originalListItem to clonedListItem 

    tempList.Add(clonedListItem); 
} 


// Do stuff to edit tempList 

return tempList; 
1

Bạn đang thêm tham chiếu đến mảng vào danh sách mới, nhưng không thực hiện một bản sao nội dung của mỗi mảng.Bản sao của bạn phải có dạng như sau:

foreach (double[] item in myList) 
{ 
    double[] copy = new double[item.Length]; 
    Array.Copy(item, copy); 
    templist.Add(copy); 
} 
0

Bạn đang sao chép tham chiếu [] kép vào danh sách mới, đây là bản sao cạn. Bạn cần một bản sao sâu và tạo các mảng kép mới để chỉnh sửa các mảng tạm thời mà không thay đổi các mảng ban đầu.

0

Bạn đang chèn tham chiếu vào mảng trong tempList, không phải bản sao của mảng. Vì vậy, nếu bạn thay đổi một giá trị trong tempList, bạn đang thay đổi mảng ban đầu.

Mã này sẽ làm việc tốt hơn:

for (int i = 0; i < myList.Count; i++) 
    { 
     var copy = new Double[myList[i].Length]; 
     Array.Copy(myList[i], copy, myList[i].Length); 
     tempList.Add(copy); 
    } 
Các vấn đề liên quan