web-dev-qa-db-fra.com

Comment puis-je former un bon délégué de prédicat pour trouver () quelque chose dans ma liste <T>?

Après avoir regardé sur MSDN, je ne sais toujours pas comment je devrais former un prédicat approprié pour utiliser la méthode Find () dans List en utilisant une variable membre de T (où T est une classe)

Par exemple:

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

À quoi devrait ressembler mon prédicat "byYear"?

(L'exemple MSDN ne parle que d'une liste de dinosaures et ne recherche qu'une valeur immuable "saurus" - Il ne montre pas comment passer une valeur dans le prédicat ...)

EDIT: J'utilise VS2005/.NET2.0, donc je ne pense pas que la notation Lambda soit disponible pour moi ...

EDIT2: Suppression de "1999" dans l'exemple parce que je peux vouloir "rechercher" par programme en fonction de différentes valeurs. Exemple changé pour la gamme de voitures de 1980 à 2000 en utilisant la boucle for-do.

23
Pretzel

Ok, dans .NET 2.0, vous pouvez utiliser des délégués, comme ceci:

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);
}
29
Matt Hamilton

Vous pouvez utiliser une expression lambda comme suit:

myCar = carList.Find(car => car.Year == 1999);
30
Dan Finucane

Ou vous pouvez utiliser un délégué anonyme:

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

Comme vous ne pouvez pas utiliser lambda, vous pouvez simplement le remplacer par un délégué anonyme.

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

Hmm. En y réfléchissant davantage, vous pouvez utiliser le curry pour renvoyer un prédicat.

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

Vous pouvez maintenant transmettre le résultat de cette fonction (qui est un prédicat) à votre méthode Find:

my99Car = cars.Find(byYear(1999));
my65Car = cars.Find(byYear(1965));
2
Matt Hamilton

Vous pouvez également l'utiliser:

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