C# 中的查询

2023-10-20 18:57:56 浏览数 (2)

本文将介绍C#一种非常重要的数据处理方式——查询。例如我想筛选产品中大于10美元的产品,那么C#不同版本都是如何完成查询的呢?

C# 1

C# 1没有什么技巧,我们需要在循环里判断价格,实现方式非常通俗易懂,但是代码又长又不够美观

代码语言:javascript复制
using System;

namespace Demo
{
    static void Main(string[] args)
    {
        ArrayList products = Product.GetProducts();
        foreach(Product item in products)
        {
            if (item.Price > 10)
            {
                Console.WriteLine(item.Name);
            }
        }
    }
}

C# 2

C# 2稍微进行了一点改进,变量test的初始化使用了匿名方法,而print变量的初始化使用了C# 2的另一个特性——方法组转换,它简化了从现有方法创建委托的过程。

代码语言:javascript复制
using System;
using System.Collections.Generic;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Product> products = Product.GetProducts();

            Predicate<Product> test = delegate (Product p) { return p.Price > 10m; };
            List<Product> matches = products.FindAll(test);

            Action<Product> print = Console.WriteLine;
            matches.ForEach(print);

            Console.ReadKey();
        }
    }
}

上述代码并没有比C# 1简单,但是它强大了很多

具体地说,它使我们可以非常轻松地更改测试条件并对每个匹配项采取单独地操作。涉及的委托变量(testprint)可以传递给一个方法——相同的方法可以用于测试完全不同的条件以及执行完全不同的操作。当然,可以将所有测试和打印都放到一条语句中

代码语言:javascript复制
List<Product> products = Product.GetProducts();
products.FindAll(delegate (Product p) { return p.Price > 10m; })
        .ForEach(Console.WriteLine);

这样更好一些,但是delegate(Product p)还是很爱是,大括号也是。它们是代码中不和谐音符,有损可读性。如果一直进行相同的测试和执行相同的操作,我还是喜欢C# 1的版本。

C# 3

C# 3拿掉了以前将实际的委托逻辑包裹起来的许多无意义的东西, 从而有了极大的改进

代码语言:javascript复制
List<Product> products = Product.GetProducts();
foreach(Product product in products.Where(p => p.Price > 10m))
{
    Console.WriteLine(product);
}

Lambda表达式将测试放在了一个非常恰当的位置。再加上一个有意义的方法名,你甚至可以大声读出代码,几乎不用怎么思考就能明白代码的含义。C# 2的灵活性也得到了保留——传递给Where的参数值可以来源于一个变量。此外,如果愿意,完全可以使用Action<Product>,而不是硬编码的Console.WriteLine调用

总结

C# 2中的匿名方法有助于问题的可分离性;C#中,Lambda表达式则增加了可读性

0 人点赞