关于c#:如何声明内联谓词?

关于c#:如何声明内联谓词?

How do you declare a Predicate Delegate inline?

我正在使用C#。

因此,我有一个包含一些字段的对象,实际上并不重要。
我有这些对象的通用列表。

1
2
3
4
List<MyObject> myObjects = new List<MyObject>();
myObjects.Add(myObject1);
myObjects.Add(myObject2);
myObjects.Add(myObject3);

因此,我想根据某些条件从列表中删除对象。
例如,myObject.X >= 10.
我想使用RemoveAll(Predicate< T > match)方法来做到这一点。

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


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

显式委托

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

拉姆达

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

加成:

明智的表现是平等的。实际上,两种语言构造在编译时都会生成相同的IL。这是因为C#3.0本质上是对C#2.0的扩展,因此可以编译为C#2.0构造:)


Lambda C#3.0方式:

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

匿名委托C#2.0的方式:

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

而且,对于VB家伙来说,VB 9.0 lambda方法是:

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

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


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

要么

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

要么

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

谓词是一个接受参数并返回布尔值的委托。

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

1)使用内联Lambda表达式

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

2)使用匿名功能

1
2
3
4
RemoveAll(delegate(myObject obj){

  return obj.x >=10;
})

3)使用谓词委托

1
2
3
4
5
Predicate<myObject> matches = new Predicate<myObject>(IsEmployeeIsValid);
RemoveAll(matches);

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

3)明确声明一个委托并指向一个函数

1
2
3
4
public delegate bool IsInValidEmployee (Employee emp);

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

//实际功能

1
2
3
4
5
6
7
public static bool IsEmployeeInValid(Employee emp)
{
    if (emp.Id > 0 )
        return true;
    else
        return false;
}


推荐阅读