最近回顾了下基础知识,看了金旭亮老师的一些视频,通过一个代码的重构演示了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); } }
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); } }
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); } }
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:写博客真是个体力活,代码整理了好久,佩服那些园子的大神