2014-11-05 19 views
11

Trong C#, nếu tôi có List<T> và tôi có đối tượng thuộc loại T, làm cách nào để thay thế một mục cụ thể trong List<T> bằng đối tượng loại T?Thay thế đối tượng trong danh sách đối tượng

Dưới đây là những gì tôi đã cố gắng:

List<CustomListItem> customListItems = new List<CustomListItem>(); 
CustomListItem customListItem1 = new CustomListItem() { name = "Item 1", date = DateTime.MinValue}; 
CustomListItem customListItem2 = new CustomListItem() { name = "Item 2", date = DateTime.MinValue }; 
CustomListItem customListItem3 = new CustomListItem() { name = "Item 3", date = DateTime.MinValue }; 

customListItems.Add(customListItem1); 
customListItems.Add(customListItem2); 
customListItems.Add(customListItem3); 

CustomListItem newCustomListItem = new CustomListItem() { name = "Item 4", date = DateTime.Now }; 

customListItem2 = customListItems.Where(i=> i.name == "Item 2").First(); 
customListItem2 = newCustomListItem; 

Trong đoạn mã trên, tôi muốn thay thế customListItem2 với newCustomListItem.

Tôi có phải xóa mục trong danh sách và sau đó chèn mục mới không? Tôi không thể thực hiện một bài tập đơn giản là customListItem2 = newCustomListItem?

Cách hiệu quả nhất để thay thế một mục trong danh sách bằng một mục khác là gì?

Cảm ơn trước

+0

Bạn đã kiểm tra http: // stackoverflow. com/questions/17188966/how-to-replace-list-item-in-best-way? – haim770

+0

Bổ sung vào các giải pháp đã được đăng, bạn cũng nên triển khai Equals/GetHashCode cho loại tùy chỉnh của mình, nếu không hoạt động ở đâu/chỉ mục của bạn có thể không tìm được phần tử phù hợp. – HimBromBeere

Trả lời

24

Bạn phải thay thế mặt hàng, chứ không phải giá trị customListItem2. Chỉ cần thay thế sau:

customListItem2 = customListItems.Where(i=> i.name == "Item 2").First(); 
customListItem2 = newCustomListItem; 

Với điều này:

customListItem2 = customListItems.Where(i=> i.name == "Item 2").First(); 
var index = customListItems.IndexOf(customListItem2); 

if(index != -1) 
    customListItems[index] = newCustomListItem; 

Edit:

Như Roman R. tuyên bố trong một chú thích, bạn có thể thay thế các .Where(predicate).First() bởi một đơn giản First(predicate):

customListItem2 = customListItems.First(i=> i.name == "Item 2"); 
+0

Cảm ơn bạn. Đẹp và đơn giản. – user3736648

+1

Bạn có thể thay thế .Where bằng .Đầu tiên ở vị trí đầu tiên và xóa nó khỏi đầu. Nó sẽ là kết quả tương tự nhưng với mã sạch hơn và nhanh hơn. Làm như sau: customListItem2 = customListItems.First (i => i.name == "Item 2"); –

+0

@RomanR. cảm ơn cho tip, chỉnh sửa câu trả lời của tôi. :) – Abbas

7
var customListItems = new List<CustomListItem>(); 
var customListItem1 = new CustomListItem() { name = "Item 1", date = DateTime.MinValue }; 
var customListItem2 = new CustomListItem() { name = "Item 2", date = DateTime.MinValue }; 
var customListItem3 = new CustomListItem() { name = "Item 3", date = DateTime.MinValue }; 

customListItems.Add(customListItem1); 
customListItems.Add(customListItem2); 
customListItems.Add(customListItem3); 

var newCustomListItem = new CustomListItem() { name = "Item 4", date = DateTime.Now }; 

customListItems[customListItems.FindIndex(x => x.name == "Item 2")] = newCustomListItem; 

hoặc

public static class ListExtensions 
{ 
    public static void Replace<T>(this List<T> list, Predicate<T> oldItemSelector , T newItem) 
    { 
     //check for different situations here and throw exception 
     //if list contains multiple items that match the predicate 
     //or check for nullability of list and etc ... 
     var oldItemIndex = list.FindIndex(oldItemSelector); 
     list[oldItemIndex] = newItem; 
    } 
} 

và sau đó

customListItems.Replace(x => x.name == "Item 2", newCustomListItem); 
+0

Cách tiếp cận mở rộng có sử dụng phản chiếu không? Nó chắc chắn là thuận tiện hơn với mã này, và tôi đã đi tuyến đường này. Chỉ cần tự hỏi về bất kỳ hit hiệu suất nào. – dunwan

+0

Không, nó không sử dụng sự phản chiếu. @dunwan – dotctor

+0

Với giải pháp này danh sách chỉ được lặp lại một lần. Với câu trả lời được chấp nhận hai lần. Nhưng thường hay không phải là trường hợp không tìm thấy nên được xử lý. Nếu không tìm thấy mục thì FindIndex trả về -1. – noox

1

nếu chuỗi các danh sách không quan trọng đối với bạn thì bạn có thể thử này

CustomListItem newCustomListItem = new CustomListItem() { name = "Item 4", date = DateTime.Now }; 

customListItem2 = customListItems.Where(i=> i.name == "Item 2").First(); 

customListItems.Remove(customListItem2); 
customListItems.Add(newCustomListItem); 
Các vấn đề liên quan