zoukankan      html  css  js  c++  java
  • 委托 Lambda表达式 LINQ 技术演变

    最近回顾了下基础知识,看了金旭亮老师的一些视频,通过一个代码的重构演示了LINQ由来,也对委托,lambda表达式有了新的认识,在此做一笔记,也和大家交流。

    1,先使用一个简单的例子,查找输出奇数的功能

    static void FindOddNumbers()
    {
        var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
        var result = new List<int>();
        foreach (var item in nums)
        {
            if (num%2 !=0)
            {
                result.Add(item);
            }
        }
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }
    }

    2,将判断提取为一个方法

    static bool IsOdd(int num)
    {
        return num%2 !=0;
    }

    然后查找方法就可以修改为

    static void FindOddNumbers()
    {
        var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
        var result = new List<int>();
        foreach (var item in nums)
        {
            if (IsOdd(item))
            {
                result.Add(item);
            }
        }
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }
    }
    View Code

     3,将数据处理功能独立成一个方法

    static IEnumerable<int> FilterIntegers(IEnumerable<int> List)
    {
        var result = new List<int>();
        foreach (var item in List)
        {
            if (IsOdd(item))
            {
                result.Add(item);
            }
        }
        return result;
    }

    代码修改为,数据处理,数据显示功能就分开了

    static void FindOddNumbers()
    {
        var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
        var result = FilterIntegers(nums);
        
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }
    }
    View Code

    4,引入委托,允许外部临时的指定条件,选择奇数还是偶数

    //增加偶数判断方法
    static bool IsEven(int num)
    {
        return num%2 == 0;
    }
    
    //定义一个 返回值为bool类型的委托
    private delegate bool PredicateDelegate(int value);
    
    //过滤整数 这个函数,增加一个委托参数
    static IEnumerable<int> FilterIntegers(IEnumerable<int> List, PredicateDelegate predicate)
    {
        var result = new List<int>();
        foreach (var item in List)
        {
            if (predicate(item))
            {
                result.Add(item);
            }
        }
        return result;
    }
    
    //修改查找奇数 现在过滤就比较灵活,就可以传入Isodd,IsEven来过滤奇数还是偶数
    static void FindOddNumbers()
    {
        var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
        var result = FilterIntegers(nums,IsOdd);
        //result = FilterIntegers(nums,IsEven); 
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }
    }
    
    //这里也可初始化一个委托,然后传入一个委托
    
     PredicateDelegate myDelegate = IsOdd;
     var result = FilterIntegers(nums, myDelegate);
     
    //委托也可以这样,用一个匿名函数来初始化
    PredicateDelegate myDelegate = delegate(int num)
    {
        return num%2 != 0;
    };
    //用lambda表达式,就能简化这一部分代码
    PredicateDelegate myDelegate = num => { return num % 2 != 0; };
    //进一步简化
    PredicateDelegate myDelegate = num => num % 2 != 0; 

    用lambda表达式两种基本格式
      1,(input parameters)=>表达式
      2,(input parameters)=>{语句;}
    只有一个输入参数时,()可以省略;
    方法主体只有一条return语句时,return 关键字也可以省略

    那么就可以删除委托,直接传递一个lambda表达式

    var result = FilterIntegers(nums, num => num % 2 != 0);

    5,引入泛型委托,使方法不单依赖于整形

    //定义一个泛型的委托
    private delegate bool PredicateGenericDelegate<T>(T value);
    //修改过滤整形方法, 现在这个方法不单依赖整形
    static IEnumerable<T> Filter<T>(IEnumerable<T> List
            , PredicateGenericDelegate<T> predicate)
    {
        var result = new List<T>();
        foreach (var item in List)
        {
            if (predicate(item))
            {
                result.Add(item);
            }
        }
        return result;
    }

    6,使用系统定义的泛型委托Func<T> ,简化代码

    //删除泛型委托的定义,代码修改为
    static IEnumerable<T> Filter<T>(IEnumerable<T> List
        , Func<T,bool> predicate)
    {
        var result = new List<T>();
        foreach (var item in List)
        {
            if (predicate(item))
            {
                result.Add(item);
            }
        }
        return result;
    }
    //---------------------------------------------------------------------------------------------------
    //使用lambda表达式
    //删除IsOdd,IsEven 这两个函数 ,代码修改为
    static void FindOddNumbers()
    {
        var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
        var result = Filter(nums, num=>num%2!=0);
        //result = FilterIntegers(nums,num=>num%2==0); 
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }
    }
    View Code

    7,引入泛型扩展方法,让代码依赖于抽象类型而不是具体类

    public static class MyExtensions
    {
        //让代码依赖于抽象类型而不是具体类
        public static IEnumerable<T> Filter<T>(this IEnumerable<T> list, Func<T, bool> predicate)
        {
            foreach (var item in list)
            {
                if (predicate(item))
                    yield return item;
            }
        }
    }
    
    // 删除Filter<T> 这个函数,修改查找方法
    static void FindOddNumbersWhere()
    {
        var nums = new int[] {0,1,2,3,4,5,6,7,8,9};
        var result = nums.Where(num => num % 2 != 0).Where(num => num % 3 == 0);
        // result = nums.Filter(num => num % 2 != 0).Filter(num => num % 3 == 0);    
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }
    }
    
    //可查看一下Where方法定义一致,Filter方法就实现了基类库中Where方法
    // 方法定义where一致,代码用 Filter来替换
    public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

    8,LINQ

    //LINQ 查询与Where扩展方法,本质上是一致的,LINQ方式代码更具有可读性
    static void FindOddNumbersLinq()
    {
        var nums = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        var result = from num in nums
                    where num%2 != 0 && num%3 == 0
                    select num;
        foreach (var item in result)
        {
            Console.WriteLine(item);
        }
    
    }

    ps:写博客真是个体力活,代码整理了好久,佩服那些园子的大神

    博文作者:困了
    博文出处:http://www.cnblogs.com/jjcl521
    本文版权归作者和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作!
  • 相关阅读:
    LeetCode15 3Sum
    LeetCode10 Regular Expression Matching
    LeetCode20 Valid Parentheses
    LeetCode21 Merge Two Sorted Lists
    LeetCode13 Roman to Integer
    LeetCode12 Integer to Roman
    LeetCode11 Container With Most Water
    LeetCode19 Remove Nth Node From End of List
    LeetCode14 Longest Common Prefix
    LeetCode9 Palindrome Number
  • 原文地址:https://www.cnblogs.com/jjcl521/p/4830045.html
Copyright © 2011-2022 走看看