《程序员》推荐我的.NET书架

创建人: 《程序员》
.NET推出以来,随之而来的相关图书铺天盖地,但真正有深度的、可以反复参考的、值得收藏的却不多见,笔者在这里介绍三本图书,它们的风格、目标和内容大相径庭,但却从不同的角度充实、提高开发者的技能。

《Applied Microsoft .NET Framework Programming 程序设计》
[美] Jeffrey Richter著 商丽媛译
北京:清华大学出版社,2002
这本书的名气就不用笔者累赘了。这是一本有关.NET框架的公共语言运行库的书,它不是针对某种特定编程语言的编程技术书籍,也不专门针对Windows窗体,XML Web服务,Web窗体等特定领域,但书中提出的各项技术都适用于这些应用程序类型。书中通过大量的代码示例准确、深入地说明了CLR和FCL部分类的工作原理和功能(这也是Jeffrey Richter的一贯风格,正是这点使他的书倍受读者喜爱和推崇),可惜的是这些代码主要以C#的形式出现,使用VB.NET和托管C++的读者恐怕要有点头疼了。在Jeffrey Richter的眼里,最适合他用来讲述的语言却是IL,幸亏他只在少数地方使用。
要更好地阅读此书,面向对象编程的知识是必需的,因为所有的.NET框架特性都是面向对象的。如果你还不太熟悉这些,找一本讲解面向对象编程的书看看会很收益。比较遗憾的是,这本经典图书的中文版翻译质量不高,建议读者对照英文版来阅读。

《 C#高级编程 》
Simon Robinson k.Scott Allen等著
杨浩 杨铁男等译
北京:清华大学出版社,2002
这本书秉承Wrox公司一贯的“Programmer to Programmer”的理念,它的定位是讲述最新的.NET编程技术,站在程序员的角度,指导程序员学习实用开发技术。书的内容共分为六个部分,几乎覆盖了.NET全部的技术主题。第一、二部分分别介绍了c#语言的背景知识和.NET环境中的编程规则。第三部分介绍如何使用ADO.NET访问数据库,文件和注册表操作,以及目录和Active Directory交互等。第四部分介绍如何编写在网站上运行的组件,如何编写网页。第五部分介绍.NET对处理COM和COM+的支持,并讨论如何编写与这些技术交互的C#代码。第六部分介绍一些高级论题,包括使用GDI+绘图、Windows服务、远程服务和安全性。
如果你想了解某个编程技术,比如:ADO.NET数据访问或者在COM中使用.NET组件,这本书对你很有价值。但中文翻译版同样出现奇怪的现象:Professional C# (Beta 2 Edition)的中文版书名是《 C#高级编程 》,而其后的《Professional c# 2nd Edition》却被标以《 C#高级编程(第二版) 》(特版精品)。

《 .NET系统架构与开发 》
曾登高编著
北京:电子工业出版社,2003
这本书是一本在.NET平台上开发应用程序的指南。书的宗旨不是讲解基本的编程知识,而且它围绕着.NET系统架构对各种编程方案、编程技巧进行了详细地论述和比较。
这本书的主要目的是对项目开发中可能遇到的典型问题给出各种可行的解决方案,并对各方案的适用情形、优势和劣势进行了详细的讨论,帮助开发者有效地进行应用程序开发。全书共分三章,第一章讲述了.NET的一些重要概念和术语;第二章深入分析了数据层、逻辑层和表现层的具体实现技术;第三章对应用程序开发周期中的部署、团队开发、性能、调试和安全问题进行了专题研究。如果你正在.NET平台上开发项目,相信这本书可以给你许多有益的建议和帮助。遗憾的是,这本书的结构显得略微松散,有些地方的翻译质量同样不尽人意。
现在,让我们来看一小段代码。
namespace test
{
public class test
{
static void Main(string[] args)
{
baseClass class1=new myClass();
Console.WriteLine(“Get1方法:”+class1.Get1());
Console.WriteLIne(“Get2方法:”+class1.Get2());
Console.ReadLine();
}
}
public class baseClass
{
public virtual string Get1()
{return “基类虚拟方法Get1”;}

public string Get2()
{return “基类非虚拟方法Get2”;}
}
public class myClass:baseClass
{
public override string Get1()
{return “继承类方法Get1”;}
public new string Get2()
{return “继承类方法Get2″;}
}
}
运行结果如下:
Get1方法:继承类Get1方法
Get2方法:基类非虚拟Get2方法

这正是我们希望的结果,你也许很想知道CLR为何如此聪明,翻开你手中的经典图书。《 C#高级编程 》(附录A面向对象编程的原则)会这样告诉你:“如果方法不是virtual,编译器就是用声明的引用类型。这时,不管class1引用的是什么,都应调用baseClass的Get2方法。如果方法是virtual,编译器就会生成代码,在运行时检查class1引用实际指向哪个实例,然后确定这个实例属于哪个类,并调用适当的Get1的重写方法。每次执行语句时,需要确定应调用那个重载方法。”
好的,解释得非常清楚了。可还是有些人不会满足,他们想知道更多:编译器是如何处理这个问题的?说明这样的问题正是《 APPLIED MICROSOFT .NET FRAMEWORK PROGRAMMING(影印版) 》的特色之一。你可以从中找到如下的阐述:“通过查看元数据,CLR可以判断出一个非静态方法是虚方法还是非虚拟方法。然而,CLR在调用方法时。没有用到该信息。CLR提供了两条IL指令用于调用一个方法:call和callvirt。call IL指令根据引用的类型调用方法,callvirt IL指令根据所指向的对象的类型调用方法。在编译源代码时,编译器知道是否应该调用一个虚方法,并发出合适的call或callvirt IL指令。”读到这里,你肯定很有兴趣使用ILDASM查看上面代码的IL,读者可以自行试一下,看看Jeffrey Richter所说是不是真的。另外,《 APPLIED MICROSOFT .NET FRAMEWORK PROGRAMMING(影印版) 》对它涉及的主题都给出了最全面的阐述,这个问题其他方面,比如被封闭类型的虚方法调用,虚方法版本控制,这些问题在书中同样给出了解释。
《 APPLIED MICROSOFT .NET FRAMEWORK PROGRAMMING(影印版) 》和《 C#高级编程 》两书中对许多问题的讲述都具有上面所讲的特点,比如:程序集、引用类型和值类型、装箱、拆箱、字符串等等。碰到这些问题时,建议读者先阅读《 C#高级编程 》一书中的相关内容,然后再到《 APPLIED MICROSOFT .NET FRAMEWORK PROGRAMMING(影印版) 》中寻找剖析,这样也许可以加快理解的速度。另外,这样的比较并不是说明两本书的高低,两本书的目标和侧重点本来就不相同。
许多读者大概都有过学车的经历。踩油门,挂档,把握方向盘,好像不是很难,在空场地练一会就OK了,但如果你这样就大摇大摆地上路,结果可就难说了。
《 C#高级编程 》是我阅读的第一本.NET图书,我从中学会了许多的编程技术。《 APPLIED MICROSOFT .NET FRAMEWORK PROGRAMMING(影印版) 》是我阅读的第二本.NET图书,通过它我了解了CLR和FCL部分类的工作原理和功能,它有助于我编写高质量的代码。之后我还翻看了一些其他的.NET图书,但感觉内容都平淡无奇,千篇一律,没有闪光点和太大的价值。前段时间由于工作的关系,我接触了《 .NET系统架构与开发 》一书,它就像当时我学开车时指导我的老师傅,他用丰富的经验洞察着路上的情形并提示着我应该做什么,让我收益匪浅。《 .NET系统架构与开发 》介绍了.NET框架中应用程序构造、部署、调试、性能、安全等诸多方面的实践经验,文章均由微软从事10年以上编程经验的资深程序员撰写,如果你正在.NET上开发应用程序,相信它可以给你许多有益的建议和指导。
你写过这样的代码吗?

void DoQuery(string Id) {
SqlConnection sql=new SqlConnection(@”data source=localhost;” +
“user id=sa;password=password;”);
sql.Open();
sqlstring= “SELECT hasshipped” +
” FROM shipping WHERE id='” + Id + “‘”;
SqlCommand cmd = new SqlCommand(sqlstring,sql);
???

这段代码有问题吗?我们不妨来看看《 .NET系统架构与开发 》书中的分析。
这段代码存在严重的安全缺陷。原因有三:第一,到SQL Server的连接使用系统管理员账号(sa);第二,系统管理员sa账号的密码使用“password”的聪明做法!第三,真正值得担忧的问题是SQL语句sqlstring构成方式,如果用户输入ID–1001,你将得到这样的语句:SELECT hasshipped FROM shipping WHERE id = ‘1001’,这是没有任何问题的。不妙的是攻击者不会这么善良,他们会输入”‘1001’ DROP table shipping–“,这时你得到的就是下面的语句:

SELECT hasshipped FROM
shipping WHERE id = ‘1001’
DROP table shipping — ‘;

等你发现shipping表莫名其妙地被删除时,许多东西就难以挽救了。不幸的是,类似这样的代码在许多的图书中是司空见惯的。

One thought on “《程序员》推荐我的.NET书架

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注