43

So I have an object which has some fields, doesn't really matter what. I have a generic list of these objects.

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

So I want to remove objects from my list based on some criteria. For instance, myObject.X >= 10. I would like to use the RemoveAll(Predicate<T> match) method for to do this.

I know I can define a delegate which can be passed into RemoveAll, but I would like to know how to define this inline with an anonymous delegate, instead of creating a bunch of delegate functions which are only used in once place.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Curtis
  • 1,189
  • 2
  • 11
  • 22

4 Answers4

58

There's two options, an explicit delegate or a delegate disguised as a lamba construct:

explicit delegate

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

lambda

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

Performance wise both are equal. As a matter of fact, both language constructs generate the same IL when compiled. This is because C# 3.0 is basically an extension on C# 2.0, so it compiles to C# 2.0 constructs

Neuron
  • 5,141
  • 5
  • 38
  • 59
Erik van Brakel
  • 23,220
  • 2
  • 52
  • 66
15

The lambda C# 3.0 way:

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

The anonymous delegate C# 2.0 way:

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

And, for the VB guys, the VB 9.0 lambda way:

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

Unfortunately, VB doesn't support an anonymous delegate.

Mark Brackett
  • 84,552
  • 17
  • 108
  • 152
  • Why should VB want anonymous delegates when it has lambdas? And yes, the next version will have multi-line lambdas and lambdas that don't return a value (= `Sub`s). – Konrad Rudolph Sep 12 '08 at 15:01
  • 2
    Because of the reasons you just stated - multiline statements, and functions that don't return a value. Good to know it'll be in the next version, but C# has had it since 2005. – Mark Brackett Sep 12 '08 at 16:11
11
  //C# 2.0
  RemoveAll(delegate(Foo o){ return o.X >= 10; });

or

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

or

  Predicate<Foo> matches = delegate(Foo o){ return o.X >= 10; });
  //or Predicate<Foo> matches = o => o.X >= 10;
  RemoveAll(matches);
Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
2

Predicate is a delegate which takes an param and returns a boolean.

We can do the same in following ways

1) Using inline Lambda expression

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

2) Using anonymous function

RemoveAll(delegate(myObject obj){

  return obj.x >=10;
})

3) Using Predicate delegate

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

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

3) Declaring a delegate explicitily and pointing to a function

public delegate bool IsInValidEmployee (Employee emp);

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

// Actual function

public static bool IsEmployeeInValid(Employee emp)
{
    if (emp.Id > 0 )
        return true;
    else
        return false;
}
Nayas Subramanian
  • 2,269
  • 21
  • 28