zoukankan      html  css  js  c++  java
  • 泛型委托 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、结构

     

    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>

     效果如图:

     

     很清楚了。^_^ 

  • 相关阅读:
    Linux 下的类似Windows下Everything的搜索工具
    windows和linux环境下制作U盘启动盘
    程序调试手段之gdb, vxworks shell
    LeetCode 1021. Remove Outermost Parentheses (删除最外层的括号)
    LeetCode 1047. Remove All Adjacent Duplicates In String (删除字符串中的所有相邻重复项)
    LeetCode 844. Backspace String Compare (比较含退格的字符串)
    LeetCode 860. Lemonade Change (柠檬水找零)
    LeetCode 1221. Split a String in Balanced Strings (分割平衡字符串)
    LeetCode 1046. Last Stone Weight (最后一块石头的重量 )
    LeetCode 746. Min Cost Climbing Stairs (使用最小花费爬楼梯)
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2040702.html
Copyright © 2011-2022 走看看