2008-10-28 15 views
21

Sau khi tìm kiếm trên MSDN, nó vẫn còn chưa rõ ràng đối với tôi như thế nào tôi nên tạo thành một vị ngữ thích hợp để sử dụng phương thức Find() trong Danh sách sử dụng một biến thành viên của T (T là một lớp)Làm cách nào để tạo thành một đại biểu vị ngữ tốt cho Tìm() trong Danh sách <T> của tôi?

Ví dụ:

public class Car 
{ 
    public string Make; 
    public string Model; 
    public int Year; 
} 

{ // somewhere in my code 
    List<Car> carList = new List<Car>(); 
    // ... code to add Cars ... 

    Car myCar = new Car(); 

    // Find the first of each car made between 1980 and 2000 
    for (int x = 1980; x < 2000; x++) 
    { 
     myCar = carList.Find(byYear(x)); 
     Console.Writeline(myCar.Make + myCar.Model); 
    } 
} 

Vị từ "byYear" của tôi trông như thế nào?

(Ví dụ MSDN chỉ nói về một danh sách các loài khủng long và chỉ tìm kiếm một giá trị bất biến "saurus" - Nó không hiển thị như thế nào để vượt qua một giá trị vào vị ...)

EDIT: Tôi đang sử dụng VS2005/.NET2.0, vì vậy tôi không nghĩ rằng ký hiệu Lambda có sẵn cho tôi ...

EDIT2: Đã xóa "1999" trong ví dụ vì tôi có thể muốn "Tìm" theo chương trình dựa trên các giá trị khác nhau. Ví dụ đã thay đổi thành phạm vi ô tô từ 1980 đến 2000 bằng cách sử dụng vòng lặp for-do.

+0

Tôi hỏi một tương tự [câu hỏi] (http://stackoverflow.com/questions/200151/search-for-object-in-generic-list) và có một số câu trả lời thực sự tuyệt vời! –

Trả lời

29

Ok, trong .NET 2.0, bạn có thể sử dụng các đại biểu, như vậy:

static Predicate<Car> ByYear(int year) 
{ 
    return delegate(Car car) 
    { 
     return car.Year == year; 
    }; 
} 

static void Main(string[] args) 
{ 
    // yeah, this bit is C# 3.0, but ignore it - it's just setting up the list. 
    List<Car> list = new List<Car> 
    { 
     new Car { Year = 1940 }, 
     new Car { Year = 1965 }, 
     new Car { Year = 1973 }, 
     new Car { Year = 1999 } 
    }; 
    var car99 = list.Find(ByYear(1999)); 
    var car65 = list.Find(ByYear(1965)); 

    Console.WriteLine(car99.Year); 
    Console.WriteLine(car65.Year); 
} 
+0

* cười với mã C# 3.0 * Tôi ghen tuông. Đoán tôi nên nâng cấp lên VS2008, huh? Cảm ơn đã giúp đỡ! – Pretzel

+0

Biến "var car99 =" ... khiến tôi hơi khó chịu. Trong trường hợp này, tôi sẽ có nhiều khả năng sử dụng "Car car99 =" ... Có lẽ tốt nhất được thảo luận ở nơi khác - http://stackoverflow.com/questions/41479/use-of-var-keyword-in-c –

+0

Điều gì tôi có thể nói không? Tôi là một hạt nhân var. –

2

Hmm. Suy nghĩ thêm về nó, bạn có thể sử dụng currying để trả về một vị từ.

Func<int, Predicate<Car>> byYear = i => (c => c.Year == i); 

Bây giờ bạn có thể vượt qua là kết quả của hàm này (đó là một vị) để tìm phương pháp của bạn:

my99Car = cars.Find(byYear(1999)); 
my65Car = cars.Find(byYear(1965)); 
+0

Tôi nghĩ Find() muốn có một số tiền là , không phải là Func . Đã thử điều này nó sẽ không biên dịch trên một danh sách trong 3.0 ...? – Codewerks

+0

Mã này sử dụng Predicate . Nó biên dịch tốt. "byYear" trả về một Predicate , sau đó được chuyển tới cars.Find(). –

27

Bạn có thể sử dụng một biểu thức lambda như sau:

myCar = carList.Find(car => car.Year == 1999); 
14

Hoặc bạn có thể sử dụng một đại biểu ẩn danh:

Car myCar = cars.Find(delegate(Car c) { return c.Year == x; }); 

// If not found myCar will be null 
if (myCar != null) 
{ 
    Console.Writeline(myCar.Make + myCar.Model); 
} 
+0

Oooh, đại biểu vô danh. Điều này có thể được tốt trong một pinch. Cảm ơn! (oh, và chào mừng bạn đến StackOverflow.) – Pretzel

+0

Nó phá vỡ Edit + Tiếp tục mặc dù không may ... –

7

Vì bạn không thể sử dụng lambda, bạn chỉ có thể thay thế bằng đại biểu ẩn danh.

myCar = carList.Find(delegate(Car car) { return car.Year == i; }); 
1

Bạn có thể sử dụng điều này quá:

var existData = 
    cars.Find(
    c => c.Year== 1999);