2009-02-17 54 views
240

您能向我解釋;C#中的謂詞代表

  • 什麼是謂詞委託?
  • 我們應該在哪裏使用謂詞?
  • 使用謂詞時的最佳實踐?

描述源代碼可以理解的,

感謝所有答覆!

回答

305

謂詞是返回truefalse的功能。謂詞委託是對謂詞的引用。

因此,基本上謂詞代表是對返回truefalse的函數的引用。謂詞對於過濾值列表非常有用 - 以下是一個示例。

using System; 
using System.Collections.Generic; 

class Program 
{ 
    static void Main() 
    { 
     List<int> list = new List<int> { 1, 2, 3 }; 

     Predicate<int> predicate = new Predicate<int>(greaterThanTwo); 

     List<int> newList = list.FindAll(predicate); 
    } 

    static bool greaterThanTwo(int arg) 
    { 
     return arg > 2; 
    } 
} 

現在,如果你使用的是C#3你可以使用lambda來代表一個更清潔的方式斷言:

using System; 
using System.Collections.Generic; 

class Program 
{ 
    static void Main() 
    { 
     List<int> list = new List<int> { 1, 2, 3 }; 

     List<int> newList = list.FindAll(i => i > 2); 
    } 
} 
+0

@Andrew野兔:在你的第一個代碼片段應該是`yeild return`而不是?或者它是如何工作的,它是如何遍歷整個列表的? – VoodooChild 2011-09-26 16:42:33

+4

@VoodooChild:請記住,序列中的每個元素將依次調用謂詞*。所以`greaterThanTwo`具有`return`而不是`yield return`,因爲它是爲你處理序列的`FindAll`方法。 – 2011-09-26 21:36:20

9

只是一個返回布爾值的委託。它在過濾列表中使用很多,但可以在任何地方使用。

List<DateRangeClass> myList = new List<DateRangeClass<GetSomeDateRangeArrayToPopulate); 
myList.FindAll(x => (x.StartTime <= minDateToReturn && x.EndTime >= maxDateToReturn): 
7

有上謂詞here的好文章,雖然它從.NET2時代的,所以在那裏沒有提及lambda表達式。

79

從Andrew關於c#2和c#3的回答開始,你也可以爲它們內聯一個搜索函數(見下面)。

using System; 
using System.Collections.Generic; 

class Program 
{ 
    static void Main() 
    { 
     List<int> list = new List<int> { 1, 2, 3 }; 

     List<int> newList = list.FindAll(delegate(int arg) 
          { 
           return arg> 2; 
          }); 
    } 
} 

希望這會有所幫助。

2

如果在VB 9(VS2008)是,謂詞是一個複雜的功能:

Dim list As New List(Of Integer)(New Integer() {1, 2, 3}) 
Dim newList = list.FindAll(AddressOf GreaterThanTwo) 
... 
Function GreaterThanTwo(ByVal item As Integer) As Boolean 
    'do some work' 
    Return item > 2 
End Function 

或者你也可以寫你的謂詞作爲一個lambda,只要它是唯一一個表達:

Dim list As New List(Of Integer)(New Integer() {1, 2, 3}) 
Dim newList = list.FindAll(Function(item) item > 2) 
4

基於謂詞的搜索方法允許一個方法委託或lambda表達式來決定給定的元素是否爲 謂詞是一個簡單的委託接受一個對象,並返回真或假「匹配」。: 公共委託布爾謂詞(T對象);

static void Main() 
     { 
      string[] names = { "Lukasz", "Darek", "Milosz" }; 
      string match1 = Array.Find(names, delegate(string name) { return name.Contains("L"); }); 
      //or 
      string match2 = Array.Find(names, delegate(string name) { return name.Contains("L"); }); 
      //or 
      string match3 = Array.Find(names, x => x.Contains("L")); 


      Console.WriteLine(match1 + " " + match2 + " " + match3);  // Lukasz Lukasz Lukasz 
     } 
     static bool ContainsL(string name) { return name.Contains("L"); } 
3

什麼是謂詞委託?

1)謂詞是一個返回true或false的特性。這個概念已經出現在.net 2.0框架中。 2)它與lambda表達式(=>)一起使用。它將泛型作爲參數。 3)它允許定義謂詞函數並將其作爲參數傳遞給另一個函數。 4)這是一個Func的特殊情況,因爲它只需要一個參數並且總是返回一個布爾值。

在C#名稱空間:

namespace System 
{ 
    public delegate bool Predicate<in T>(T obj); 
} 

它是在系統命名空間中定義。

我們應該在哪裏使用Predicate Delegate?

我們應該在以下情況下使用謂詞代表:

1)對於泛型集合搜索項目。 例如

var employeeDetails = employees.Where(o=>o.employeeId == 1237).FirstOrDefault(); 

2)縮短代碼,並返回基本示例true或false:

Predicate<int> isValueOne = x => x == 1; 
現在

,呼叫上述謂詞:

Console.WriteLine(isValueOne.Invoke(1)); // -- returns true. 

3)匿名方法也可以被分配到Predicate代表類型如下:

Predicate<string> isUpper = delegate(string s) { return s.Equals(s.ToUpper());}; 
    bool result = isUpper("Hello Chap!!"); 

有關謂詞的任何最佳實踐?

使用Func,Lambda表達式和委託代替謂詞。