2008-10-28 11 views
21

Посмотрев на MSDN, пока неясно мне, как я должен сформировать правильный предикат использовать метод Find() в списке, используя переменную-член Т (где Т класс)Как создать хороший предикат делегата для поиска() что-то в моем списке <T>?

Например:

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); 
    } 
} 

Как выглядит мой предикат «byYear»?

(пример MSDN говорит только о списке динозавров и поиск только для неизменного значения «Saurus» - это не показывает, как передать значение в предикат ...)

EDIT: Я использую VS2005/.NET2.0, поэтому я не думаю, что для меня имеется нотация Лямбда ...

EDIT2: Удалено «1999» в примере, потому что я могу «найти» программно на основе разные значения. Пример изменен на диапазон автомобилей с 1980 по 2000 год с использованием цикла for-do.

+0

Я задавал подобный вопрос [] (http://stackoverflow.com/questions/200151/search-for-object-in-generic-list) и получили некоторые действительно отличные ответы! – 2008-10-28 05:35:38

ответ

29

Хорошо, в .NET 2.0 вы можете использовать делегатов, например:

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# 3.0 * Я ревную. Думаю, я должен перейти на VS2008, а? Спасибо за помощь! – Pretzel 2008-10-28 02:20:11

2

Хм. Подумав об этом, вы можете использовать currying для возврата предиката.

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

Теперь вы можете передать результат этой функции (который является предикатом) в ваш метод Find:

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

Я думаю Find() хочет, чтобы Predicate , а не Func . Пробовал это, он не будет компилироваться в List в 3.0 ...? – Codewerks 2008-10-28 02:25:45

+0

Этот код использует предикат . Он компилируется просто отлично. «byYear» возвращает предикат , который затем передается на cars.Find(). – 2008-10-28 02:43:18

27

Вы можете использовать лямбда-выражение следующим образом:

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

Или вы можете использовать анонимный делегат:

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); 
} 
7

Поскольку вы не можете использовать лямбда, вы можете просто заменить его анонимный делегат.

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

Вы можете использовать это тоже:

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

 Смежные вопросы

  • Нет связанных вопросов^_^