2008-09-12 70 views
40

我正在使用C#。你如何聲明一個謂詞委託內聯?

所以我有一個對象,它有一些領域,並不重要什麼。 我有這些對象的通用列表。

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

所以我想根據一些標準從我的列表中刪除對象。 例如,myObject.X >= 10. 我想用RemoveAll(Predicate<T> match)方法來做到這一點。

我知道我可以定義一個可以傳遞給RemoveAll的委託,但我想知道如何用匿名委託內聯定義這個內聯,而不是創建一堆僅用於一次的委託函數。

回答

52

有兩個選擇,一個明確的委託或僞裝成蘭巴構建一個委託:

明確委託

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結構:)

15

拉姆達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拉姆達方式:

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

不幸的是,VB不支持匿名代表。

+0

爲什麼VB希望匿名委託時,它具有lambda表達式? 是的,下一個版本將有多行lambda表達式和lambda表達式,它們不返回值(=`Sub`s)。 – 2008-09-12 15:01:40

10
//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); 
0

謂詞是一個代表它接受一個PARAM,並返回一個布爾值。

我們可以做同樣在以下幾個方面

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; 
}