《C#高效编程》读书笔记08-推荐使用查询语法而不是循环
C#语言中并不缺少控制程序流程的结构,for、while、do/while和foreach
等都可以做到这一点。但我们还有更好的方式:查询语法(query syntax)
下面这段代码演示了用命令式的方式填充一个数组,然后将其内容输出到控制台:
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()));
//扩展
public static class Extensions
{
public static void ForAll<T>(this IEnumerable<T> sequence, Action<T> action)
{
foreach(T item in sequence)
action(item);
}
}
这只是个简单的操作,因此你可能看不到太多的好处。确实如此,不过你可以继续看看其他一些问题。
很多操作要处理嵌套循环。例如,用0~99的整数生成所有的(X, Y)二元数组,使用嵌套循环也不难:
private static IEnumerable<Tuple<int, int>> ProduceIndices()
{
for(int x = 0; x < 100; x++)
for(int y = 0; y < 100;y++)
yield return Tuple.Create(x, y);
}
当然也可以用查询来生成同样的数据:
private static IEnumerable<Tuple<int, int>> QueryIndices()
{
return from x in Enumerable.Range(0, 100)
from y in Enumerable.Range(0, 100)
select Tuple.Create(x, y);
}
看上去还是差不多,我们继续更改一下问题,我们需要返回的二元组按照其离远点距离的逆序排列。
下面两个不同的方法能生成同样正确的结果:
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, point2) =>
(
point2.Item1 * point2.Item1 + point2.Item2 * point2.Item2
).CompareTo(
point1.Item1 * point1.Item1 + point1.Item2 * point1.Item2
));
}
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);
}
现在就应该感觉到明显不同了。相比而言,命令式的版本非常难以理解,要是没有注释或文档,后续维护人员将要重读整段代码才能进行开发。
另外,查询语法比循环结构能提供更具组合性的API。查询语法将很自然的把代码分解成小块代码,每一块仅仅对序列中元素进行单一的操作。查询语法的延迟执行模型也让开发者能将这些单一的操作组合成多步操作,且在一次遍历序列时完整执行。
于此同时,方法调用也能同样实现:
private static IEnumerable<Tuple<int, int>> MethodIndices()
{
return Enumerable.Range(0, 100)
.SelectMany(x => Enumerable.Range(0, 100).(x, y) => Tuple.Create(x, y))
.Where(pt => pt.Item1 + pt.Item2 < 100)
.OrderByDescending(pt => pt.Item1 * pt.Item1 + pt.Item2 * pt.Item2);
}
综上所述,当你编写循环时,首先看看能不能用查询语法实现。若是无法使用查询语法,再看看是否可以使用方法调用语法替代。
《C#高效编程》读书笔记08-推荐使用查询语法而不是循环的更多相关文章
- 1-3 - C#语言习惯 - 推荐使用查询语法而不是循环
C#语言中并不缺少控制程序流程的结构,for.while.do-while和foreach等都可以做到这点. 历史上所有计算机语言设计者都不曾遗漏这些重要的循环控制结构. 不过我们还有一个更好的方式: ...
- CSAPP 并发编程读书笔记
CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...
- 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化
<深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- Node.js高级编程读书笔记Outline
Motivation 世俗一把,看看前端的JavaScript究竟能做什么. 顺便检验一下自己的学习能力. Audience 想看偏后台的Java程序员关于前端JavaScript的认识的职业前端工程 ...
- python高级编程读书笔记(一)
python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...
- unix环境高级编程-读书笔记与习题解答-第一篇
从这周开始逐渐的进入学习状态,每天晚上都会坚持写c程序,并且伴随对这本书的深入,希望能写出更高质量的读书笔记和程序. 本书的第一章,介绍了一些关于unix的基础知识,在这里我不想去讨论linux到底是 ...
- MacTalk·人生元编程 - 读书笔记
简介 <MacTalk·人生元编程>是一本随笔文集,主要内容来自作者的微信公众平台"MacTalk By 池建强".本书撰写于2013年,书中时间线却不止于此.作者以一 ...
- UNIX网络编程--读书笔记
会集中这段时间写UNIX网络编程这本书的读书笔记,准备读三本,这一系类的文章会不断更新,一直会持续一个月多,每篇的前半部分是书中讲述的内容,每篇文章的后半部分是自己的心得体会,文章中的红色内容是很重要 ...
随机推荐
- 关于web中注册倒数的问题(亲测)
<title></title> <script type="text/javascript"> var leftSecond ...
- Unity编辑器的扩展:IMGUI
IMGUI 介绍 所有关于 Editor 的相关 UI,包括 Inspector.Hierarchy.Window.Game 视图上动态创建的那些半透明 UI.还有 Scene 视图上可添加的辅助显示 ...
- Linux服务器监控工具--Nmon介绍
一.Nmon介绍(详细请参考百度百科) 是一款分析 AIX 和 Linux 性能的免费工具,这个高效的工具可以工作于任何哑屏幕.telnet 会话.甚至拨号线路.另外,它并不会消耗大量的 CPU 周期 ...
- python+selenium UI自动化不同浏览器之间的切换
class register(): ROBOT_LIBRARY_SCOPE = 'GLOBAL' def __init__(self): pass # m默认打开chrome def open_bro ...
- 会过vip怎么赚钱?大学生,宝妈创业圈子
会过vip怎么赚钱?是骗局吗1.如果说会过Vip不赚钱,那么一定是我们的没有时间去真心的热爱她:如果你对她如果你对它抱着一颗平和的心,认真的去分享,认真的去听一些前辈的经验,赚钱真的不是难事:2.如果 ...
- 当有“Button1.Attributes.Add("onclick", "return confirm('你确定要保存修改吗?')");”时,验证控件失效的解决方法
同一个页面用Js和服务器验证控件OnClientClick提交问题 实现功能: 点击Button按钮的OnClientClick事件,不会影响服务器验证控件的验证功能 ...
- unity 查找游戏中隐藏的物体
在Hierarchy 有时会隐藏一些游戏物体,我们需要在游戏的时候将其激活状态变为true 我们发现通过 GameObject.Find("隐藏物体名字") 是查找不到隐藏对象的 ...
- 基础篇---memcache
十分钟学会memcache,比你想象的要简单 转发:https://baijiahao.baidu.com/s?id=1588816843517136163&wfr=spider&fo ...
- uva 1153 顾客是上帝(贪心)
uva 1153 顾客是上帝(贪心) 有n个工作,已知每个工作需要的时间q[i]和截止时间d[i](必须在此前完成),最多能完成多少个工作?工作只能串行完成,第一项任务开始的时间不早于时刻0. 这道题 ...
- 简单几步实现 IOS UITextField输入长度的控制
在ios开发过程中,我们有时候需要对UITextField的输入长度进行控制,比如输入手机号码最大长度为11位等,而ios自身又不像android那样可以设置输入框的输入长度,接下来通过简单几步实现这 ...