2012-03-24 28 views
70

ứng dụng của tôi sử dụng một danh sách như thế này:Làm cách nào để tìm một phần tử cụ thể trong Danh sách <T>?

List<MyClass> list = new List<MyClass>();

Sử dụng phương pháp Add, một thể hiện của MyClass được thêm vào danh sách.

MyClass cung cấp, trong số những người khác, các phương pháp sau:

public void SetId(String Id); 
public String GetId(); 

Làm thế nào tôi có thể tìm thấy một trường hợp cụ thể của MyClass bằng phương tiện của việc sử dụng phương pháp GetId? Tôi biết có phương pháp Find, nhưng tôi không biết liệu điều này có hiệu quả ở đây không ?!

Trả lời

172

Sử dụng một biểu thức lambda

MyClass result = list.Find(x => x.GetId() == "xy"); 

Lưu ý: C# có một built-in cú pháp đối với tài sản. Thay vì viết phương thức Set và Get, hãy viết

private string _id; 
public string Id 
{ 
    get 
    { 
     return _id; 
    } 
    set 
    { 
     _id = value; 
    } 
} 

value là từ khóa theo ngữ cảnh chỉ được biết đến trong bộ truy cập được đặt. Nó đại diện cho giá trị được gán cho thuộc tính.

Vì mẫu này thường được sử dụng, C# cung cấp các thuộc tính được tự động triển khai. Đó là một phiên bản ngắn của mã trên; tuy nhiên, biến ủng hộ bị ẩn và không thể truy cập (nó có thể truy cập từ bên trong lớp trong VB, tuy nhiên).

public string Id { get; set; } 

Bạn chỉ có thể sử dụng các thuộc tính như thể bạn đang truy cập vào một lĩnh vực:

var obj = new MyClass(); 
obj.Id = "xy";  // Calls the setter with "xy" assigned to the value parameter. 
string id = obj.Id; // Calls the getter. 

Sử dụng tài sản, bạn sẽ tìm kiếm cho các hạng mục trong danh sách như thế này

MyClass result = list.Find(x => x.Id == "xy"); 

Bạn cũng có thể sử dụng tự động triển khai tính nếu bạn cần một thuộc tính chỉ đọc:

public string Id { get; private set; } 

này cho phép bạn thiết lập các Id trong lớp nhưng không phải từ bên ngoài. Nếu bạn cần phải đặt nó trong các lớp thừa kế cũng bạn cũng có thể bảo vệ các setter

public string Id { get; protected set; } 

Và cuối cùng, bạn có thể kê khai tài sản như virtual và ghi đè lên chúng trong thừa kế các lớp, cho phép bạn để cung cấp triển khai khác nhau cho getters và setters; cũng như đối với các phương thức ảo thông thường.


Vì C# 6.0 (Visual Studio 2015, Roslyn), bạn có thể viết tự động tính getter chỉ với một initializer inline

public string Id { get; } = "A07"; // Evaluated once when object is initialized. 

Bạn cũng có thể khởi tạo các thuộc tính getter chỉ trong các nhà xây dựng để thay thế. Thuộc tính tự động chỉ có getter là đúng thuộc tính chỉ đọc, không giống như các thuộc tính được tự động triển khai với trình đặt riêng tư.

này cũng làm việc với đọc-ghi tự động tính:

public string Id { get; set; } = "A07"; 

Bắt đầu với C# 6.0 bạn cũng có thể viết các thuộc tính như các thành viên biểu hiện thân

public DateTime Yesterday => DateTime.Date.AddDays(-1); // Evaluated at each call. 
// Instead of 
public DateTime Yesterday { get { return DateTime.Date.AddDays(-1); } } 

Xem: .NET Compiler Platform ("Roslyn")
                  New Language Features in C# 6

Bắt đầu với C# 7.0, cả hai, phương thức getter và setter, có thể được viết với các cơ quan biểu:

public string Name 
{ 
    get => _name;        // getter 
    set => _name = value;      // setter 
} 

Lưu ý rằng trong trường hợp này setter phải là một biểu hiện. Nó không thể là một tuyên bố. Ví dụ trên hoạt động, bởi vì trong C#, một phép gán có thể được sử dụng như một biểu thức hoặc như một câu lệnh. Giá trị của biểu thức gán là giá trị được gán trong đó bản thân nhiệm vụ là một tác dụng phụ. Điều này cho phép bạn chỉ định giá trị cho nhiều biến cùng một lúc: x = y = z = 0 tương đương với x = (y = (z = 0)) và có tác dụng tương tự như các câu lệnh x = 0; y = 0; z = 0;.

+2

Great câu trả lời, cảm ơn. Đối với hoạt động db nó sẽ trông giống như thế này: 'IQueryable result = db.Set () .Find (// chỉ id ở đây //). ToList(); ' Nó sẽ biết rằng bạn đang tìm kiếm chính Chìa khóa. Chỉ để biết thêm thông tin thôi. – Edgar

+0

Tôi biết đây là câu trả lời cũ, nhưng tôi muốn tách riêng và đặt thành các phương thức khác nhau sao cho giá trị không được đặt ngẫu nhiên trong khi so sánh. –

+0

@JoelTrauger: So sánh đọc thuộc tính và do đó chỉ gọi cho getter. –

14
var list = new List<MyClass>(); 
var item = list.Find(x => x.GetId() == "TARGET_ID"); 

hoặc nếu có chỉ là một và bạn muốn thực thi một cái gì đó giống như SingleOrDefault có thể là những gì bạn muốn

var item = list.SingleOrDefault(x => x.GetId() == "TARGET"); 

if (item == null) 
    throw new Exception(); 
7

Hãy thử:

list.Find(item => item.id==myid); 
3

Bạn có thể giải quyết vấn đề của bạn chính xác nhất với biến vị ngữ được viết bằng cú pháp phương thức ẩn danh:

MyClass found = list.Find(item => item.GetID() == ID); 
4

Bạn cũng có thể sử dụng LINQ phần mở rộng:

string id = "hello"; 
MyClass result = list.Where(m => m.GetId() == id).First(); 
+3

hoặc quá tải khác của First: 'MyClass result = list.First (m => m.GetId() == id); ' –

3

Hoặc nếu bạn không thích sử dụng LINQ bạn có thể làm điều đó theo cách cũ-học:

List<MyClass> list = new List<MyClass>(); 
foreach (MyClass element in list) 
{ 
    if (element.GetId() == "heres_where_you_put_what_you_are_looking_for") 
    { 

     break; // If you only want to find the first instance a break here would be best for your application 
    } 
} 
Các vấn đề liên quan