Linq原理1(LINQ简介及其相关的C#扩展)
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
{
public class Common
{
//定义一个委托
public delegate bool IntFilter(int i);
public static int[] FilterArrayOfInts(int[] ints, IntFilter filter)
{
ArrayList alist = new ArrayList();
foreach (var i in ints)
{
if (filter(i))
{
alist.Add(i);
}
}
return (int[])alist.ToArray(typeof(int));
}
}
public class Application
{
//判断是否是奇数
public static bool IsOdd(int i)
{
return ((i & 1) == 1);
}
}
class Program
{
static void Main(string[] args)
{
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//方案一
int[] oddNum = Common.FilterArrayOfInts(nums, Application.IsOdd);
//方案二 使用匿名的方法
// int[] oddNum = Common.FilterArrayOfInts(nums, delegate(int i) { return ((i & 1) == 1); });
//方案三 使用lambda表达式
// int[] oddNum = Common.FilterArrayOfInts(nums,i=>((i&1)==1));
foreach (int i in oddNum)
{
Console.WriteLine(i);
}
Console.Read();
}
}
}
通过Common.FilterArrayOfInts(nums, Application.IsOdd)第二个参数把方法传到委托中去,这样做的好处是根据具体的需要,传不同的方法,这样灵活性就强,同时代码重用性好。这种方法的劣势在于如果Filter方法所需的筛选规则没有通用性,它的代码没有任何重用性,属于一次性的产品,就没有必备专门编写Application类去管理这些方法规则,在这里使用委托显得有些麻烦。对于这种情况可以采用第二种方案.(见代码注释),匿名方法的确定逻辑不能太复杂,否则可读性不好.第三种方案解决了第二种方案缺陷。(注意lambda表达式i => ((i & 1) == 1)要和委托public delegate bool IntFilter(int i);相吻合)
下面来研究下lambda表达式
i => ((i & 1) == 1) // "=>"左边的是参数,右边是函数体
int[] nums = new int[] { 6, 2, 7, 1, 9, 3 };
IEnumerable<int> numsLessThanFour = nums.Where(i => i < 4).OrderBy(i => i);
注: "=>"左边 i 的数据从nums 数组来(i就是 nums中的一个个数据)