2008-10-28 4 views
21

Después de mirar en MSDN, aún no está claro para mí cómo debería formar un predicado correcta de usar el método Find() en la lista utilizando una variable miembro de T (donde T es una clase)¿Cómo puedo formar un buen delegado predicado para encontrar() algo en mi lista <T>?

Por ejemplo:

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

¿Cómo debería ser mi predicado "byYear"?

(el ejemplo de MSDN sólo habla de una lista de los dinosaurios y sólo busca un valor inmutable "saurus" - que no muestra cómo pasar un valor en el predicado ...)

EDIT: Estoy usando VS2005/.NET2.0, así que no creo que la notación Lambda esté disponible para mí ...

EDIT2: Se eliminó "1999" en el ejemplo porque es posible que desee "Buscar" programáticamente en función de valores diferentes. El ejemplo cambió a la gama de autos de 1980 a 2000 utilizando el ciclo for-do.

+0

me hizo una [pregunta] similar (http://stackoverflow.com/questions/200151/search-for-object-in-generic-list) y obtuve algunas respuestas realmente excelentes! –

Respuesta

29

De acuerdo, en .NET 2.0 puede usar delegados, así:

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

* se ríe del código C# 3.0 * Estoy celoso. Supongo que debería actualizar a VS2008, ¿eh? ¡Gracias por la ayuda! – Pretzel

+0

La var en "var car99 =" ... me pone un poco incómodo. En este caso, es más probable que use "Car car99 =" ... Probablemente se discuta mejor en otro lugar donde: http://stackoverflow.com/questions/41479/use-of-var-keyword-in-c –

+0

What ¿Puedo decir? Soy un loco. –

2

Hmm. Pensando más en eso, podría usar currying para devolver un predicado.

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

Ahora usted puede pasar el resultado de esta función (que es un predicado) a su método Find:

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

Creo que Find() quiere un predicado , no un Func . ¿Intenté esto no compilará en una lista en 3.0 ...? – Codewerks

+0

Este código no utiliza predicado . Compila muy bien. "byYear" devuelve un Predicado , que luego se pasa a cars.Find(). –

27

Se puede utilizar una expresión lambda de la siguiente manera:

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

o puede utilizar un delegado anónimo:

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, delegado anónimo. Esto podría ser bueno en un apuro. ¡Gracias! (Ah, y bienvenidos a StackOverflow.) – Pretzel

+0

Se rompe Editar + Continuar aunque desafortunadamente ... –

7

Como no se puede utilizar lambda que sólo puede sustituirlo por un delegado anónimo.

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

Se puede usar esta demasiado:

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