2008-09-12 19 views
40

Estoy usando C#.¿Cómo declaras un delegado predicado en línea?

Así que tengo un objeto que tiene algunos campos, en realidad no importa qué. Tengo una lista genérica de estos objetos.

List<MyObject> myObjects = new List<MyObject>(); 
myObjects.Add(myObject1); 
myObjects.Add(myObject2); 
myObjects.Add(myObject3); 

Así que quiero eliminar objetos de mi lista según algunos criterios. Por ejemplo, myObject.X >= 10. Me gustaría utilizar el método RemoveAll(Predicate<T> match) para hacer esto.

Sé que puedo definir un delegado que se puede pasar a RemoveAll, pero me gustaría saber cómo definir esto en línea con un delegado anónimo, en lugar de crear un grupo de funciones de delegado que solo se utilizan en una sola ubicación.

Respuesta

52

Hay dos opciones, un delegado explícita o un delegado disfrazado como un constructo lamba:

delegado explícita

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

lambda

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

Adición:

Rendimiento sabio ambos son iguales. Como cuestión de hecho, ambos constructos de lenguaje generan la misma IL cuando se compila. Esto es debido a que C# 3.0 es básicamente una extensión de C# 2.0, por lo que se compila en C# 2.0 construcciones :)

15

La lambda C# 3.0 manera:

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

El anónima manera delegado C# 2.0:

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

Y, para los chicos VB, VB 9.0 lambda manera:

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

Desafortunadamente, VB no admite una delegado anónimo.

+0

Por qué debería querer VB delegados anónimos cuando tiene lambdas? Y sí, la próxima versión tendrá líneas múltiples lambdas y lambdas que no devuelven un valor (= 'Sub's). –

+2

Por las razones que acaba de indicar: instrucciones de línea múltiple y funciones que no devuelven un valor. Es bueno saber que estará en la próxima versión, pero C# lo tiene desde 2005. –

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

o

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

o

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

predicado es un delegado que toma un parámetro y devuelve un valor booleano.

Podemos hacer lo mismo en las formas siguientes

1) Uso de línea de expresión Lambda

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

2) Usando función anónima

RemoveAll(delegate(myObject obj){ 

    return obj.x >=10; 
}) 

3) El uso de predicados delegado

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

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

3) declarar un delegado explicitily y apuntando a una función

public delegate bool IsInValidEmployee (Employee emp); 

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

// función real

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