Comment former un bon délégué prédicat à Find () quelque chose dans ma liste < T >?
Question
Après avoir regardé sur MSDN, il m'est toujours difficile de savoir comment former un prédicat approprié pour utiliser la méthode Find () dans List à l'aide d'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 " by byYear " prédicat ressembler?
(L'exemple MSDN ne parle que d'une liste de dinosaures et recherche uniquement 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: Supprimé "1999" dans l'exemple car je souhaite peut-être " Rechercher " de manière programmée sur différentes valeurs. Exemple modifié pour la gamme de voitures de 1980 à 2000 en utilisant une boucle for-do.
La solution
Ok, dans .NET 2.0, vous pouvez utiliser des délégués, comme suit:
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);
}
Autres conseils
Vous pouvez utiliser une expression lambda comme suit:
myCar = carList.Find(car => car.Year == 1999);
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);
}
Puisque 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; });
Hmm. En y réfléchissant davantage, vous pouvez utiliser le currying 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));
Vous pouvez aussi utiliser ceci:
var existData =
cars.Find(
c => c.Year== 1999);