2012-11-26 32 views
12

Trong khi học C# khá nhanh, tôi đang vấp phải vấn đề cú pháp Bộ sưu tập này.C# Cú pháp sưu tập hộp danh sách C#

Tôi đã thêm một số đối tượng thuộc loại MyItem của riêng tôi vào danh sách lstData. Bây giờ tôi cần phải tìm kiếm trong listbox này và suy nghĩ của việc sử dụng các ký hiệu LINQ thanh lịch như:

lstData.Items.Where(x => x.Text == SearchString) 

nhưng Items của một ListBox không có .Where(), mặc dù tôi đã bổ sung thêm các "sử dụng System.Linq ; " không gian tên.

Vì vậy, tôi đã cố gắng:

foreach (MyItem item in (MyItem)lstData.Items) 

nhưng điều này mang đến cho các lỗi xây dựng: Không thể chuyển đổi loại 'System.Windows.Forms.ListBox.ObjectCollection' thành 'MySandbox.frmListboxDemo.MyItem'.

tôi đã quản lý để viết một cái gì đó hoàn toàn khả thi:

 for (int i = 0; i < lstData.Items.Count; i++) 
     { 
      MyItem item = (MyItem)lstData.Items[i]; 
      if (item.Text == SearchString) 
      { 
       lstData.SetSelected(i, true); 
       break; 
      } 
     } 

và một phiên bản tương tự như:

 var item_enum = lstData.Items.GetEnumerator(); 
     while (item_enum.MoveNext()) { etc etc... } 

mà hóa ra là 2 dòng lâu hơn, và không tìm những gì có thể thay thế 'var' .

Tôi không thực sự chắc chắn tôi hiểu cách sử dụng Bộ sưu tập, ObjectCollections, Enumerators vv, nhưng tôi rất mong muốn tìm hiểu. Đặc biệt nếu có thể có phiên bản .Where() và/hoặc tốt hơn.


Cảm ơn mọi câu trả lời của bạn. Tôi đã kết thúc với giải pháp này:

 var item_iter = lstData.Items.Cast<MyItem>() 
          .Where(x => x.Text.Trim().ToLower() == txtItemName.Text); 
     foreach (MyItem item in item_iter) 
     { 
      int i = lstData.Items.IndexOf(item); 
      lstData.SetSelected(i, true); 
      break; 
     } 

Tôi không biết nếu điều này là thực sự tốt hơn nhiều so với cách "fortran" (xem ở trên), nhưng nó dạy tôi phương pháp tôi có thể sử dụng trong các truy vấn kháC# C.

+0

sử dụng '.OfType ' ... –

Trả lời

7

Hãy thử sử dụng Cast<T> trước tiên để thực hiện truyền cho loại bạn mong đợi. Đó là:

lstData.Items.Cast<MyItem>().Where(x => x.Text == SearchString)

+0

Lỗi bây giờ là: 'Syst em.Linq.Enumerable.Cast (System.Collections.IEnumerable) 'là một' phương thức ', không hợp lệ trong ngữ cảnh đã cho – Roland

+1

@Roland Xin lỗi, tôi đã quên '()' để gọi nó. (Tôi sẽ sửa chữa mọi thứ và thêm nhiều hơn như @Jan đã làm, nhưng đã được gọi đi) –

+1

Chris, cảm ơn sự giúp đỡ của bạn. Tôi tìm thấy() bản thân mình sau khi một số phản ánh. Tôi đã làm việc này. Bây giờ tôi chỉ cần đọc tất cả các bình luận khác cho những điểm thú vị. – Roland

17

Bộ sưu tập các mặt hàng được đánh máy không mạnh mẽ bộ sưu tập. Bạn có thể sử dụng các phương pháp IEnumerable<T>.OfType() hoặc IEnumerable<T>.Cast() mở rộng để có được sự xâm nhập vào thế giới LINQ nơi bạn có thể lọc các mục của bạn:

var filteredItems = lstData.Items.OfType<MyItem>().Where(i => i.Prop == val); 

Sự khác biệt giữa Cast và OfType là:

  • OfType<T> sẽ chỉ trả lại các mục có thể chuyển sang Loại T
  • Cast<T> sẽ không thành công, khi ít nhất một mục nằm trong bộ sưu tập không thể chuyển thành T
+0

Câu trả lời hoàn hảo .. một điều nhỏ tuy nhiên, cần phải có dấu ngoặc() sau OfType - OfType () .Where (... –

+0

@JasonHiggins Phải, tôi đã sửa chữa nó – Jan

1

ListBox.ObjectCollection thực hiện IEnumerable, nhưng không phải là chung IEnumerable<T>, mà hầu hết các phương thức Linq yêu cầu.

Một cách để có được IEnumerable<T> VÀ giải quyết vấn đề đúc của bạn trong một bước là sử dụng Cast<T>:

lstData.Items.Cast<MyItem>().Where(x => x.Text == SearchString) 
0

Cố gắng tạo ra một danh sách ra khỏi các mục:

(new ListBox()).Items.OfType<ListViewItem>().Where(......); 

Có lẽ lý do là vì nó được xây dựng với phiên bản trước đó của .net