【C# in depth 第三版】温故而知新(1)
声明
本文欢迎转载,原文地址:http://www.cnblogs.com/DjlNet/p/7192354.html
前言
关于这本书(《深入理解C# 第三版》)的详细情况以及好坏,自行搜索即可,我就不啰里啰嗦的,此文责在备份,意在记录一下第二次阅读当中发现原先囫囵吞枣之处,也为了记忆深刻吧。对这里还有一本《Clr via C# 第四版》也准备二次阅读,关于精度细读章节,知乎传送门( 赵姐夫的回答 ): https://www.zhihu.com/question/27283360。就在昨天(9月9号)北京和上海相继展开了技术分享会(有同步直播),这里要给北京的sqlserver演讲的老哥点赞,讲得不错挺落地和实在的,还有上海的分享的【.Net 微服务实战】,看了心里挺有感触的,并不是说从知识或者实践的层面领悟到有多少有多少,而是理解和明白这玩意儿为何而生,培养一点大局观和思维套路吧,毕竟在DDD、微服务大行其道的今天只有不断学习,然后温故而知新,可能才能知道它们想表达的含义吧!
这些知识你还记得么吗,\(^∀^)メ
上面扯了一些口水话,其实在学习偏架构的知识时候,那么必经之路便是对语言基础的足够掌握以及对上层框架的理解掌握,那么今天再去扯架构和框架之前就来回顾一下关于语言的一些小知识,以下是在下记录一些书中查漏补缺自个人备份记忆使用,其中可能也包含以下不常用或者小知识,大神大佬请自动忽略 ,哈哈。
误区:对象在C#中默认是通过引用传递的
我这里摘录引用书中部分描叙:首先“引用传递”的正式定义相当复杂,要涉及左值和类似的计算机科学术语,但是最重要的一点是,假如以引用传递的方式来传递一个变量,那么调用的方法可以通过更改其参数值,来改变调用者的变量值(说到这里有木有想到 ref out 关键字,是的它们就可以达到引用传递的效果)。那么默认情况,就是没有显示使用关键词的情况,引用类型变量的值才是引用(类似: 0x12345678 这种),而不是对象本身,且不需要按引用来传递参数本身,就可以更改该参数引用的那个对象的内容。例如:下面的方法更改了相关对象StringBuilder的内容,但是调用者的表达式引用的仍然是之前的那个对象:
void AppendHello(StringBuilder builder)
{
builder.Append("Hello");
}
调用这个方法时,参数值(对StringBuilder的一个引用)是以值传递的方式传递的。如果想在方法内部更改builder的变量值,如:builder=null;
对调用者来说是看不见的。
理解:JIT编译器如何处理泛型
对于所有的封闭类型,JIT的职责就是将泛型类型的IL转换为本地代码,我们以List作为例子,首先JIT为每个以值类型作为类型实参的封闭类型都创建不同的代码,理论上对于一些值类型来说,代码是可以共享的,但是JIT必须十分谨慎,不仅需要考虑空间大小的问题,还要考虑垃圾回收的问题,所以第一次创建独享的代码。那么,所有使用引用类型(string、stream、stringbuilder等)作为类型实参的封闭类型都共享相同的本地代码,之所以可以这样做,是由于所有引用都具有相同的大小(32位CLR上是4个字节,64位CLR是8个字节,在任何一个特定的CLR中所有引用具有相同的大小)。关于泛型的新增API,GetGenericTypeDefinition作用于已构造的类型,获取它的泛型类型定义和MarkGenericType作用于泛型类型的定义,返回一个已构造类型,诸如此类还有:GetGenericArguments、IsGenericTypeDefinition、IsGenericType、MarkGenericMethod、IsGenericMethod等等。
Nullable类型理解与使用null进行赋值和比较原理
注意Nullable是一个结构也就是值类型,对于例如Nullable的变量来说,直接包含了一个bool和一个int成员,而不是其他对象的引用。关于null赋值比较,原理:C#编译器允许使用null在比较和赋值时表示一个可空类型的空值。其中这样来处理的原因,相信也是从语言层面让语义更加符合自然逻辑,获得和引用类型null的同样体验。那么到底编译器关于可空值类型帮我们做了什么呐,int? a=null; if(a==null){ .... }
,与null比较其实在编译器生成IL代码中,被转换为调用a.HasValue
,对a赋值为null,其实也是调用了Nullable的构造函数创建一个空值实例而已,注意直接调用a.Value在没有真正的值提供时将会抛出异常。
注意匿名函数变量捕获
划重点:
1、捕获的是变量本身,而不是创建委托实例时它的值
2、捕获的变量的生存周期被延长了,至少和捕获它的委托一样长
3、多个委托可以捕获同一个变量
4、在循环内部,同一个变量声明实际上会引用不同的变量“实例”(这点在R#也会提示开发者)
5、如果捕获的变量不会发生改变,就不需要担心
6、在C#5或者以上修正foreach的表达含义,但是for依然需要注意。
理解Yield的工作流程和成为奠定异步Async/Await的设计基石
这里直接引用书中的代码加强记忆和再次熟悉下流程,如下图所示代码:
关于代码的执行流程那得自个儿看看,慢慢跟着执行流程,相信就能明白Yield在代码执行中起到的作用,就貌似能在不同的方法之间跳跃,总的来说可以归为几点:
1、在第一次调用MoveNext之前,CreateEnumerable中的代码不会被调用
2、所有工作在调用MoveNext时就完成了,获取Current的值不会执行任何代码
3、在yield return的位置,代码会停止执行,方法暂时返回调用者方法,在下一次执行MoveNext时有继续在下一行代码继续执行
4、在一个方法中的不同位置可以编写多个yield return语句
5、代码不会在最后的yield return处结束而是通过返回false的MoveNext调用来结束方法的执行
上面说了这么多,在看到第3和4点的时候有没有感觉到await的部分作用似曾相识,await也可以让方法返回而且可以等在那里等到结果拿到之后接着那个“断点”继续执行,而且在一个Async标记的异步方法中可以,有多个await的拆包操作,所以在一定程度上面yield在思想和设计层面上,给后面的C#5的异步埋下了铺垫。从状态机的角度来看(这块并不是很熟悉,所以说错了,请斧正)在C#5中为迭代器块而生成的状态机和那些异步函数而生成的状态机之间的相似性是惊人的。异步开发中两个复杂的问题就是:1、处理状态 2、在感兴趣的事情发生之前进行有效的暂停,迭代器使得这两个问题得以完美的解决。 这里提供一下yield实现异步的伪代码,也是书中的代码片段:(伪代码是基于CCR实现的,主要是明白它想传递表达的意思,即可代码部分看看就好)
static IEnumerator<ITask> ComputeTotalStockVal.(str.user,str.pass)
{
string token=null;
yield return Arbiter.Receive(false,AuthService.CcrCheck(user,pass),
delegate(string t){ token=t; });
IEnumerable<Holding> stocks=null;
IDictionary<string,decimal> rates=null;
yield return Arbiter.JoindReceive(false,
DbService.CcrGetStockHoldings(token),
StockService.CcrGetRate(token),
delegate(IEnumerable<Holding> s,IDictionary<string,decimal> r)
{
stocks=s;
rates=r;
});
OnRequestComplete(ComputeTotal(stocks,rates));
}
大致对上面代码做个解释说明虽然是伪代码,CCR对我们的代码进行了调用也就是调用MoveNext,第一个yield return才会执行,AuthService里面的CcrCheck方法启动一个异步请求,CCR会等待直到它完成,然后提供给它的委托来处理拿到的结果也就是token,然后接着再次调用MoveNext,方法接着执行,JoindReceive并行启动两个异步请求,在两个请求都完成的情况下,利用后续的委托去处理结果,在这之后MoveNext再次调用,就完成了全部的请求处理了。
小总结
再回看一些基础知识的时候,才发觉原来语言层面的设计不比一些高层架构的设计的重要性和观赏性差(虽然没什么可比性,哈哈),好了,天不早了,后面应该会出续篇,等这个完了之后,应该会开始对一些大家关注的点出发,脚踏实地的从代码、需求和设计层面考虑去写一些可使用的代码片段或者程序设计,用作以后参考或者借鉴。最最后,好好给自己一记耳光,咋就做人真懒呐,看看离上次发文都多长时间了,送给自己的话:从现在起做一个不那么懒的人吧!谨记!!!
【C# in depth 第三版】温故而知新(1)的更多相关文章
- 【C# in depth 第三版】温故而知新(1) (转)
声明 本文欢迎转载,原文地址:http://www.cnblogs.com/DjlNet/p/7192354.html 前言 关于这本书(<深入理解C# 第三版>)的详细情况以及好坏,自行 ...
- 【C# in depth 第三版】温故而知新(2)
声明 本文欢迎转载,原文地址:http://www.cnblogs.com/DjlNet/p/7522869.html 前言 我们接了上一篇的未完待续,接着我们的划重点之行.....哈哈 理解:LIN ...
- 微软发布 Windows Server 2016 预览版第三版,开发者要重点关注Nano Server
微软已经发布 Windows Server 2016 和 System Center 2016 第三个技术预览版,已经提供下载.Windows Server 2016 技术预览版第三版也是首个包括了容 ...
- 0038 Java学习笔记-多线程-传统线程间通信、Condition、阻塞队列、《疯狂Java讲义 第三版》进程间通信示例代码存在的一个问题
调用同步锁的wait().notify().notifyAll()进行线程通信 看这个经典的存取款问题,要求两个线程存款,两个线程取款,账户里有余额的时候只能取款,没余额的时候只能存款,存取款金额相同 ...
- APUE学习--第三版apue编译
第三版apue编译: 1. 首先在 http://www.apuebook.com/ 下载源码解压: tar zxvf src.3e.tar.gz 看完Readme可知,直接执 ...
- Radmin Server-3.5 完美绿色破解版(x32 x64通用) 第三版 + 单文件制作方法
Radmin Server v3.5 汉化破解绿色版(x32 x64通用) 第三版 下载链接: https://pan.baidu.com/s/1qYVcSQo 2016年7月8日更新第三版1.修复在 ...
- 《CLR.via.C#第三版》第一部分读书笔记(一)
最近开始仔细研读<CLR.via.C#第三版>这本书.读pdf文档确实很累.建议有条件的朋友还是买书看吧. 我的笔记用来记录我对这本书的理解,简化下逻辑,对每个部分我觉得是要点的进行归纳总 ...
- 新浪微博.Net SDK第三版源代码和示例【最后一次更新了】
时间过得飞快,距离上次SDK更新已经3年有余.随着官方的不断跟新,老版SDK的部分接口已经不能正常使用.因此在QQ群里来吐槽的.来谩骂的朋友也开始多了起来.随着时代的发展,微博已经彻底的被微信甩开,因 ...
- selenium webdriver (python) 第三版
感谢 感谢购买第二版的同学,谢谢你们对本人劳动成果的支持!也正是你们时常问我还出不出第三版了,也是你们的鼓励,让我继续学习整理本文档. 感谢乙醇前辈,第二版的文档是放在他的淘宝网站上卖的,感谢他的帮忙 ...
随机推荐
- python-桶排序
桶排序 通排序非常浪费空间, 比如需要排序的范围在0~2000之间, 需要排序的数是[3,9,4,2000], 同样需要2001个空间 注意: 通排序不能排序小数 以下为从小到大代码实现 #!/usr ...
- 关于在HTML中使用的script标签
本文是<JavaScript高级程序设计>(第三版)中的第二章的个人学习的总结. 在HTML中使用JavaScript <script>标签 在HTML5中script主要有以 ...
- hdu 6045 Is Derek lying?(思维推导)
Problem Description Derek and Alfia are good friends.Derek is Chinese,and Alfia is Austrian.This sum ...
- 四、什么是vuex
一.关于vuex刚开始学习的时候对于里面的很多名词有很陌生.很难接受这个定义,下面这个链接很好很简单通俗的解释了什么是vuex 我喜欢的vuex网址:https://zhuanlan.zhihu.co ...
- 再起航,我的学习笔记之JavaScript设计模式05(简单工程模式)
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...
- Spring学习笔记之AOP配置篇(一)
[TOC] 1. 创建并声明一个切面 首先,创建一个类,添加@Component注解使其添加到IoC容器 然后,添加@Aspect注解,使其成为一个切面 最后,在配置文件里面,使用<aop:as ...
- 安徽省2016“京胜杯”程序设计大赛_H_单身晚会
单身晚会 Time Limit: 1000 MS Memory Limit: 65536 KB Total Submissions: 53 Accepted: 16 Description ZJ和Z ...
- 【NO.10】Jmeter - 一个完整的录制脚本的过程
上1篇介绍了"使用Jmeter对一个接口地址或者一个页面地址执行N次请求",也就是你自己干了一件从"零"开始的事情. 那么这1篇介绍"如何使用Jmeter录制'访问一个接口地址或者一个页面地址'的脚本 ...
- 关于JS脚本语言的基础语法
JS脚本语言的基础语法:输出语法 alert("警告!"); confirm("确定吗?"); prompt("请输入密码");为弱 ...
- java代码_按要求输出相应沙漏
package Callatz;/* 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个"*",要求按下列格式打印******* ***** *** * ...