2012-01-04 25 views
7

Có cách nào dễ dàng về cơ bản chỉ nhận bản sao dữ liệu thay vì tham chiếu bằng phương pháp này không? Tôi đã cố gắng. ToArray(). Trường hợp() nhưng dường như vẫn vượt qua một tham chiếu.Cách lấy bản sao dữ liệu thay vì tham chiếu bằng linq/lambda trong C#?

Ví dụ:

static void Main(string[] args) 
{ 
    List<ob> t = new List<ob>(); 
    t.Add(new ob() { name = "hello" }); 
    t.Add(new ob() { name = "test" }); 

    ob item = t.Where(c => c.name == "hello").First(); 

    // Changing the name of the item changes the original item in the list<> 
    item.name = "burp"; 

    foreach (ob i in t) 
    { 
     Console.WriteLine(i.name); 
    } 

    Console.ReadLine(); 
} 

public class ob 
{ 
    public string name; 
} 

Trả lời

6

Bạn cần phải tạo một bản sao của ob của bạn mình - đó là không phải cái gì LINQ cung cấp.

+3

Cố gắng thực hiện [IClonable] (http://msdn.microsoft.com/en-us/library/system.icloneable%28v=VS.100%29.aspx) theo loại ob. Sau đó, bạn có thể sử dụng 't.Where (c => c.name ==" hello "). Đầu tiên(). Clone()'. –

3

Bạn có thể xác định một phương pháp Clone dựa trên phương pháp hiện protected MemberwiseClone:

public class Item 
{ 
    public Item Clone() 
    { 
     return (Item)this.MemberwiseClone(); 
    } 
} 

Sau đó:

ob item = t.Where(c => c.name == "hello").First().Clone(); 
2

Như ob là một lớp học, nó là một reference type và do đó bất kỳ trường hợp ob, khi được gán cho một biến khác (như đang xảy ra trong dòng ob item = t.Where(c => c.name == "hello").First();) sẽ tự động sao chép reference vào phiên bản gốc và không sao chép thực tế bản thân nó. Đây là một chủ đề .NET chung về việc sao chép đối tượng và tách biệt với LINQ/Lambda,

Để đạt được những gì bạn muốn, bạn cần phải tạo một Shallow Copy or a Deep Copy của cá thể kết quả từ phép chiếu LINQ của bạn.

Đối với lớp ob của bạn, một Sao chép Shallow sẽ đủ (ShallowCopy thường bản càng ít càng tốt trong khi DeepCopy bản mọi thứ - Một tài liệu tham khảo tốt cho sự khác biệt có thể được tìm thấy here).

Để thực hiện ShallowCopy của đối tượng, bạn có thể sử dụng đơn giản MemberwiseClone là phương pháp tích hợp sẵn kiểu đối tượng .NET, được tất cả các đối tượng thừa kế.

Để có điều gì đó quan trọng hơn, bạn sẽ phải triển khai chức năng DeepCopy của riêng mình, nhưng điều đó có thể tương đối đơn giản. Một cái gì đó tương tự như các triển khai này như được chỉ định herehere.

0

Cách dễ dàng hơn nhiều là chỉ cần tuần tự hóa dữ liệu của bạn vào json và sau đó quay lại. Nó có một hit hiệu suất nhỏ nhưng nó là an toàn hơn vì nó ít dễ bị lỗi và bạn không cần phải sửa đổi tất cả các lớp học của bạn.

chỉ cần làm:

var json = JsonConvert.SerializeObject(myObject) 
var clone = JsonConvert.DeserializeObject<T>(json) 
+0

Tại sao không gửi nó đến cơ sở dữ liệu SQL, và sau đó đọc lại? – zgnilec

+0

Trong khi không thích hợp, điều này làm việc rất tốt để đối phó với một đối tượng HttpRuntime.Cache. Miniscule hit và trở lại để hoàn thành công việc thay vì săn lùng xung quanh cho một giải pháp nhân bản cũng sẽ có một hit hiệu suất. – Stonetip

Các vấn đề liên quan