泛型委托 Predicate/Func/Action

Predicate 泛型委托
  表示定义一组条件并确定指定对象是否符合这些条件的方法。此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素。
看看下面它的定义:

// Summary:
    //     Represents the method that defines a set of criteria and determines whether
    //     the specified object meets those criteria.
    //
// Parameters:
    //   obj:
    //     The object to compare against the criteria defined within the method represented
    //     by this delegate.
    //
// Type parameters:
    //   T:
    //     The type of the object to compare.
    //
// Returns:
    //     true if obj meets the criteria defined within the method represented by this
    //     delegate; otherwise, false.

public delegate bool Predicate<T>(T obj);
类型参数介绍:
   T: 要比较的对象的类型。
   obj: 要按照由此委托表示的方法中定义的条件进行比较的对象。
   返回值:如果  obj 符合由此委托表示的方法中定义的条件,则为  true;否则为  false
看下面代码:

public   class  GenericDelegateDemo
    {
        List
< String >  listString  =   new  List < String > ()
        {
            
" One " , " Two " , " Three " , " Four " , " Fice " , " Six " , " Seven " , " Eight " , " Nine " , " Ten "
        };

        String[] arrayString 
=   new  String[]
        {
             
" One " , " Two " , " Three " , " Four " , " Fice " , " Six " , " Seven " , " Eight " , " Nine " , " Ten "
        };

        
public  String[] GetFirstStringFromArray()
        {
            
return  Array.FindAll(arrayString, (c)  =>  {  return  c.Length  <=   3 ; });
        }

        
public  List < String >  GetFirstStringFromList()
        {
            
return  listString.FindAll((c)  =>  {  return  c.Length  <=   3 ; });
        }

        
public  String[] GetFirstStringFromArray_1()
        {
            
return  Array.FindAll(arrayString, GetString);
        }

        
public  List < String >  GetFirstStringFromList_1()
        {
            
return  listString.FindAll(GetString);
        }

        
private   bool  GetString(String str)
        {
            
if  (str.Length  <=   3 )
                
return   true ;
            
else
                
return   false ;
        }
    }


(1)首先,上面以 数组和泛型List 两个集合作为演示对象,并构建集合。
(2)接着,两者同时使用各自 所有的 FindALL方法,参见如下定义:
    Array : public T[] FindAll<T>(T[] array, Predicate<T> match);
    List:public List<T> FindAll(Predicate<T> match);
    注意的是,两处的FindAll 均采用了Predicate (泛型委托)作为参数的类型。
(3)接着,使用两者方式展现 对Predicate 的使用:
    第一种:  (c) => { return c.Length <= 3; };
    第二种: GetString(String str)。
这两者在语法上明显不同,但是实际是做相同的事情,第一种是使用Lambda表达式构建的语句,关于Lambda这里不做详述,请参见笔者C#3.0特性相关文章。

补充的是你也可以这样写,

  delegate (String c){ return  c.Length <= 3 ;}
  作为 Predicate定义的参数
完整代码: 
XX.FindAll( delegate (String c) {  return  c.Length  <= 3 ; }); 
这应该称为匿名代理了。
其他使用到Predicate 有
  Array.Find , Array.FindAll , Array.Exists , Array.FindLast , Array.FindIndex ..... 
  List<T>.Find , List<T>.FindAll , List<T>.Exists , List<T>.FindLast , List<T>.FindIndex ..... 
延伸:
  除了上面提到的外,你完全可以使用Predicate 定义新的方法,来加强自己代码。

public   class  GenericDelegateDemo
{
    List
< String >  listString  =   new  List < String > ()
    {
        
" One " , " Two " , " Three " , " Four " , " Fice " , " Six " , " Seven " , " Eight " , " Nine " , " Ten "
    };

    
public  String GetStringList(Predicate < String >  p)
    {
        
foreach ( string  item  in  listString)
        {
            
if  (p(item))
                
return  item;
        }
        
return   null ;
    }

    
public   bool  ExistString()
    {
        
string  str  =  GetStringList((c)  =>  {  return  c.Length  <=   3   &&  c.Contains( ' S ' ); });
        
if  (str  ==   null )
            
return   false ;
        
else
            
return   true ;
    }
}
同样 解决了上面的问题,这里罗嗦了只是为说明Predicate的用法而已。
对于Predicate的应用当然这不是什么新鲜事情,今天细细思味一番,觉得C# 真是一门优雅的语言。
以供初学者参考。
笔者本想对以下几种泛型委托一一做些介绍和总结的,在理解Predicate的过程中,发现只要理解了泛型、委托和匿名代理,
当然你晓得Lambda表达式更好,就完全可以在适当的时候灵活应用他们了。也就是说,只是定义不同的delegate而已,
一是 你可以自己定义这样的delegate,再行使用;
二是 你需要知道象Predicate、Func、Action这样的已有好的delegate是如何定义的。或者使用的时候适当查阅下MSDN即可。
如:
Func():封装一个不具有参数但却返回  TResult 参数指定的类型值的方法。
Func(T1, T2, TResult):封装一个具有两个参数并返回  TResult 参数指定的类型值的方法,没有T2就是封装一个具有参数并....。
Action() Action(T1) Action(T2) : 封装一个方法,该方法指定数量的参数(如()无参数,(T1)一个参数,以此类推)并且不返回值。这个和Func有相似处,但无返回值而已。

提醒大家的注意的是:
  x=>x+x;
    与

  X=> {return x+x;} 是等价的。

针对解释我又结合MVC做了下练习。

 1、结构

泛型委托 Predicate/Func/Action_第1张图片 

2、如图分别在Controller 下建立PredicateController.cs;Views下建立Predicate文件夹,然后在其下建立index (View)

PredicateController.cs
using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Web;
using  System.Web.Mvc;

namespace  PredicatePractice.Controllers
{
    
public   class  PredicateController : Controller
    {
        
//
        
//  GET: /Predicate/
        
        
public  ActionResult Index()
        {
            List
< string >  StrList  =   new  List < string > () { 
            
" One " , " Two " , " Three " , " Four " , " Fice " , " Six " , " Seven " , " Eight " , " Nine " , " Ten "
            };

            
string [] arrayList  =   new   string [] {
            
" One " , " Two " , " Three " , " Four " , " Fice " , " Six " , " Seven " , " Eight " , " Nine " , " Ten "
            };
            
// 返回arrayList中长度小于3的单词数组(string[])
             string [] NewArray  =  Array.FindAll(arrayList, c  =>  c.Length  <   4 );

            
// 返回StrList中中长度小于3的单词数组(List<string>)
            List < string >  NewList  =  StrList.FindAll(c  =>  c.Length  <   4 );

            
// 利用CheckStr方法(泛型委托)来进行筛选
             string [] NewArrayUseCheckFunc  =  Array.FindAll(arrayList, CheckStr);

            
// 利用CheckStr方法(泛型委托)来进行筛选
            List < string >  NewListUseCheckPredicate  =  StrList.FindAll(CheckStr);

            ViewData[
" NewArray " =  NewArray;
            ViewData[
" NewList " =  NewList;
            ViewData[
" NewArrayUseCheckFunc " =  NewArrayUseCheckFunc;
            ViewData[
" NewListUseCheckPredicate " =  NewListUseCheckPredicate;
            
return  View();
        }

        
///   <summary>
        
///  检查字符串S长度 是否小于4
        
///   </summary>
        
///   <param name="S"></param>
        
///   <returns></returns>
         private   bool  CheckStr( string  S)
        {
            
if  (S.Length  <   4 )
                
return   true ;
            
else
                
return   false ;
        }

    }
}
index.aspx
<% @ Page Title = ""  Language = " C# "  MasterPageFile = " ~/Views/Shared/Site.Master "  Inherits = " System.Web.Mvc.ViewPage "   %>

< asp:Content  ID ="Content1"  ContentPlaceHolderID ="TitleContent"  runat ="server" >
    index
</ asp:Content >

< asp:Content  ID ="Content2"  ContentPlaceHolderID ="MainContent"  runat ="server" >

    
< h2 > Pradicatepractice
    
< br  />
        数组{"One","Two","Three","Four","Fice","Six","Seven","Eight","Nine","Ten"}
< br  />
        --------------Begin--------------
< br  />
        
< font  color ="red" >< b > string[] NewArray = Array.FindAll(arrayList, c => c.Length  <  3 );</b ></ font >< br  />
        结果:
        
<%  IList < string >  NewArray  =  (ViewData[ " NewArray " as  IEnumerable < string > ).ToList < string > ();  %>
        
<% =  Html.Display( " <br/> " %>
        
<%   for  ( int  i  =   0 ; i  <  NewArray.Count; i ++ %>
        
<%  {  %>
        
<% =  Html.Label(NewArray[i].ToString()) %>
        
<%  }  %>
        
< br  />
        ------------------------------
< br  />
        
< font  color ="red" >< b > List <  string  >  NewList = StrList.FindAll(c => c.Length  <  3 );</b ></ font >< br  />
        结果:
        
<%  IList < string >  NewList  =  (ViewData[ " NewList " as  IEnumerable < string > ).ToList < string > ();  %>
        
<%   for  ( int  j  =   0 ; j  <  NewList.Count; j ++ %>
        
<%  {  %>
        
<% =  Html.Label(NewList[j].ToString()) %>
        
<%  }  %>
        
< br  />
        ------------------------------
< br  />
        
< font  color ="red" >< b > Lstring[] NewArrayUseCheckFunc = Array.FindAll(arrayList, CheckStr); </ b ></ font >< br  />
        结果:
        
<%  IList < string >  NewArrayUseCheckFunc  =  (ViewData[ " NewArrayUseCheckFunc " as  IEnumerable < string > ).ToList < string > ();  %>
        
<%   for  ( int  k  =   0 ; k  <  NewArrayUseCheckFunc.Count; k ++ %>
        
<%  {  %>
        
<% =  Html.Label(NewArrayUseCheckFunc[k].ToString()) %>
        
<%  }  %>
        
< br  />
        ------------------------------
< br  />
        
< font  color ="red" >< b > List <  string  >  NewListUseCheckPredicate = StrList.FindAll(CheckStr); </ b ></ font >< br  />
        结果:
        
<%  IList < string >  NewListUseCheckPredicate  =  (ViewData[ " NewListUseCheckPredicate " as  IEnumerable < string > ).ToList < string > ();  %>
        
<%   for  ( int  l  =   0 ; l  <  NewListUseCheckPredicate.Count; l ++ %>
        
<%  {  %>
        
<% =  Html.Label(NewListUseCheckPredicate[l].ToString()) %>
        
<%  }  %>
        
< br  />
        ---------------End---------------
< br  />
    
</ h2 >

</ asp:Content >

 效果如图:

泛型委托 Predicate/Func/Action_第2张图片 

 很清楚了。^_^ 

你可能感兴趣的:(action)