43

所以我有一个包含一些字段的对象,这并不重要。我有这些对象的通用列表。

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

所以我想根据一些标准从我的列表中删除对象。例如,myObject.X >= 10. 我想使用 for 的RemoveAll(Predicate<T> match)方法来做到这一点。

我知道我可以定义一个可以传递给 RemoveAll 的委托,但我想知道如何用匿名委托定义这个内联,而不是创建一堆只在一次地方使用的委托函数。

4

4 回答 4

57

有两种选择,显式委托或伪装成 Lamba 构造的委托:

显式委托

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

拉姆达

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

性能方面两者是相等的。事实上,两种语言结构在编译时都会生成相同的 IL。这是因为 C# 3.0 基本上是 C# 2.0 的扩展,因此它编译为 C# 2.0 结构

于 2008-09-12T14:48:08.563 回答
15

lambda C# 3.0 方式:

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

匿名委托 C# 2.0 方式:

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

而且,对于 VB 人来说,VB 9.0 lambda 方式:

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

不幸的是,VB 不支持匿名委托。

于 2008-09-12T14:49:10.353 回答
11
  //C# 2.0
  RemoveAll(delegate(Foo o){ return o.X >= 10; });

或者

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

或者

  Predicate<Foo> matches = delegate(Foo o){ return o.X >= 10; });
  //or Predicate<Foo> matches = o => o.X >= 10;
  RemoveAll(matches);
于 2008-09-12T14:50:41.193 回答
1

Predicate 是一个委托,它接受一个参数并返回一个布尔值。

我们可以通过以下方式做同样的事情

1)使用内联 Lambda 表达式

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

2)使用匿名函数

RemoveAll(delegate(myObject obj){

  return obj.x >=10;
})

3)使用谓词委托

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

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

3)显式声明委托并指向函数

public delegate bool IsInValidEmployee (Employee emp);

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

// 实际函数

public static bool IsEmployeeInValid(Employee emp)
{
    if (emp.Id > 0 )
        return true;
    else
        return false;
}
于 2017-11-19T09:28:42.110 回答