2008-09-12 8 views
40

J'utilise C#.Comment déclarer un délégué de prédicat en ligne?

Donc j'ai un objet qui a des champs, peu importe quoi. J'ai une liste générique de ces objets. Par conséquent, je souhaite supprimer des objets de ma liste en fonction de certains critères. Par conséquent, je souhaite supprimer les objets de ma liste en fonction de certains critères. Par exemple, myObject.X >= 10. Je voudrais utiliser la méthode RemoveAll(Predicate<T> match) pour cela. Je sais que je peux définir un délégué qui peut être passé dans RemoveAll, mais j'aimerais savoir comment le définir en ligne avec un délégué anonyme, au lieu de créer un tas de fonctions déléguées qui ne sont utilisées qu'une seule fois.

Répondre

52

Il y a deux options, un délégué explicite ou un délégué déguisé en construction lamba:

délégué explicite

myObjects.RemoveAll(delegate (MyObject m) { return m.X >= 10; }); 

lambda

myObjects.RemoveAll(m => m.X >= 10); 

Addition:

Performance sage les deux sont égaux. En fait, les deux constructions de langage génèrent la même IL lorsqu'elle est compilée. Ceci est parce que C# 3.0 est essentiellement une extension sur C# 2.0, il compile en C# 2.0 constructions :)

15

La lambda façon C# 3.0:

myObjects.RemoveAll(m => m.x >= 10); 

Le délégué anonyme C façon # 2.0:

myObjects.RemoveAll(delegate (MyObject m) { 
    return m.x >= 10; 
}); 

Et, pour les gars VB, la façon lambda VB 9.0:

myObjects.RemoveAll(Function(m) m.x >= 10) 

Malheureusement, VB ne supporte pas délégué anonyme.

+0

Pourquoi devrait VB vouloir les délégués anonymes quand il a lambdas? Et oui, la prochaine version aura des lambdas et des lambdas multi-lignes qui ne renvoient pas de valeur (= 'Sub's). –

+2

Pour les raisons que vous venez d'énoncer - les instructions multilignes, et les fonctions qui ne renvoient pas de valeur. Bon à savoir ce sera dans la prochaine version, mais C# l'a eu depuis 2005. –

10
//C# 2.0 
    RemoveAll(delegate(Foo o){ return o.X >= 10; }); 

ou

//C# 3.0 
    RemoveAll(o => o.X >= 10); 

ou

Predicate<Foo> matches = delegate(Foo o){ return o.X >= 10; }); 
    //or Predicate<Foo> matches = o => o.X >= 10; 
    RemoveAll(matches); 
0

prédicat est un délégué qui prend un param et renvoie une valeur booléenne.

Nous pouvons faire la même chose façons

1) Utilisation en ligne Lambda expression

RemoveAll(p=> p.x > 2); 

2) En utilisant la fonction anonyme

RemoveAll(delegate(myObject obj){ 

    return obj.x >=10; 
}) 

3) Utilisation de prédicats délégué

Predicate<myObject> matches = new Predicate<myObject>(IsEmployeeIsValid); 
RemoveAll(matches); 

Predicate<Foo> matches = delegate(Foo o){ return o.X >= 20; }); 
RemoveAll(matches); 

3) Déclarant un délégué et en montrant explicitement en fonction

public delegate bool IsInValidEmployee (Employee emp); 

IsInValidEmployee invalidEmployeeDelegate = new IsInValidEmployee(IsEmployeeInValid); 
myObjects.RemoveAll(myObject=>invalidEmployeeDelegate(myObject); 

// Fonction actuelle

public static bool IsEmployeeInValid(Employee emp) 
{ 
    if (emp.Id > 0) 
     return true; 
    else 
     return false; 
} 
Questions connexes