zoukankan      html  css  js  c++  java
  • 使用查询语法而不是循环

          写程序,不可避免要控制程序的流程,像for, while, do/while, foreach,计算机语言的设计者都为我们提供了这些重要的循环结构,但是,这些控制结构都是属于“命令式”的,也就是说,你要告诉程序怎么去做。不过,我们拥有比循环更好的选择,这就是查询语法。与循环结构相比,查询语法属于“声明式”,你只需告诉程序,你想做什么,至于怎么做,交给程序就可以了。

    1. 更清楚的表示你的意图

    我们先来看一段采用循环的代码:

    	   int[] foo = new int[100];
                for (int num = 0; num < foo.Length; num++)
                {
                    foo[num] = num*num;
                }
    
                foreach (int i in foo)
                {
                    Console.WriteLine(i.ToString());
                }

    这是一段非常简单的代码,我们可以发现,我们关注了太多的细节实现。如果采用“声明式”的查询语法:

    	   int[] foo = (from n in Enumerable.Range(0, 100)
                             select n*n).ToArray();
                foo.ForAll((n) => Console.WriteLine(n.ToString()));

    显然,代码的可读性增强了,同时也更加易于重用。

    2. 复杂的问题依旧保持简单的书写方式

    假设我们要用0~99的整数生成所有的(X,Y)二元组,同时要求X+Y<100,最后,按照生成的点距离原点的距离逆序排列。

    如果采用循环的方式:

    	private static IEnumerable<Tuple<int,int>> ProduceIndices()
            {
                var storage = new List<Tuple<int, int>>();
    
                for (int x = 0; x < 100; x++)
                {
                    for (int y = 0; y < 100; y++)
                    {
                        if (x + y < 100)
                        {
                            storage.Add(Tuple.Create(x,y));
                        }
                    }
                }
    
                storage.Sort((point1,poing2)=>(poing2.Item1*poing2.Item1+poing2.Item2*poing2.Item2).CompareTo(
                    point1.Item1*point1.Item1+point1.Item2*point1.Item2));
                return storage;
            }

    何等“复杂”的一段代码!

    我们再来看看使用查询语法的代码:

    	private static IEnumerable<Tuple<int,int>> QueryIndices()
            {
                return from x in Enumerable.Range(0, 100)
                       from y in Enumerable.Range(0, 100)
                       where x + y < 100
                       orderby (x*x + y*y) descending
                       select Tuple.Create(x, y);
            }

    负责的问题,通过声明式的查询语法,我们依旧可以保持简单、优雅的代码。

    3. 性能比较

    相对于普通的循环,查询语法经常被提起的一个问题是性能问题。虽然我们可以很容易的设计一个比查询语法性能更加高的循环,但是,问题的关键是我们需要判断,某个特别的情况下,某个查询的效率是不是有问题。

    例如,我们将#2的例子的100改成1000,然后对比二者的性能会发现,查询语法的性能反而更高。

    总结:

    当我们需要编写循环的时候,首先要看能否用查询语法实现,如若不能,那么再看是否可以用方法调用(相对于查询语法,如LINQ有查询语法和方法调用2种方式)来代替。这样,我们写出来的代码会比循环结构更简洁一些。

    参考:《C#高效编程》

  • 相关阅读:
    d3 之deal with data
    git 使用小结
    【nodemailer】之 work with mustache
    Mustache
    【nodemailer】 初试
    【计算机基础】二.组成1(总线、输入输出)
    【计算机基础】一.概述
    Sring事务管理
    【并发编程】4.JUC中常用的锁
    【并发编程】3.线程与线程池
  • 原文地址:https://www.cnblogs.com/tian2010/p/2552805.html
Copyright © 2011-2022 走看看