揭秘Linq方法的背后

1. Linq方法

含有Linq方法的代码:

static void Main(string[] args)
{
    int[] nums = { 10, 2, 5, 6, 79, 47, 16, 4, 1, 64, 654 };
    IEnumerable<int> list = nums;
    IEnumerable<int> result = list.Where(x => x > 10);
    foreach (var item in result)
    {
        Console.WriteLine(item);
    }
}

其中list.Where(x=>x>10)为Linq方法。 Where()方法的作用为:遍历集合中的所有元素,对于每个元素都使用括号中的Lambda表达式进行结果的判断,如果结果为true,则将该元素放到返回的集合中。 括号中的条件可以反推回命名函数:

bool f(int i)
{
    return i>10;
}

2. 创建自己的Where方法

通过对于Where方法的理解,我们可以尝试自己编写Where方法。当然,Where方法不仅仅针对一种类型进行处理。但作为初学者,我们首先尝试实现上述代码中功能的Where方法。

static IEnumerable<int> MyWhere(IEnumerable<int> list,Func<int,bool> f)
{
    List<int> result = new List<int>();
    foreach (var item in list)
    {
        if (f(item))
        {
            result.Add(item);
        }
    }
    return result;
}

在调用时,使用IEnumerable<int> result = MyWhere(list,x=>x>10)来代替上述代码中的IEnumerable<int> result = list.Where(x => x > 10) ,可以看到两次运行后的结果是相同的。

第一次运行结果

第二次运行结果


3. Where方法的另一种实现方法

除了使用传统的List<T>来接收返回值以外,我们还可以通过使用yield return来实现,代码如下:

static IEnumerable<int> MyWhere(IEnumerable<int> list, Func<int, bool> f)
{
    foreach (var item in list)
    {
        if (f(item))
        {
            yield return item;
        }
    }
}

该方法与上一种的方法的区别是:使用yield return能够将满足条件的元素直接通过WriteLine进行输出,而不是使用List来接收所有满足条件的元素后,通过WriteLine来输出List中的内容。 与第一种Where的实现方法相比,数据的处理效率更高。


4. var 类型推断

在编写代码中,我们可以使用var让编译器的“类型判断”来简化类型的声明。这在Linq中常常用到。但需要注意的是:C#作为一种强类型编程语言,它的var与JavaScript中的var是不同的。当你通过赋值语句将一个var进行赋值之后,var将改变为你所赋值的类型。例如var i = 5,在之后如果你对i进行其他类型的赋值,例如i="string",此时编译器将会报错。


本文章使用limfx的vscode插件快速发布