这是我第一本参与翻译的书,下面是勘误表。非常厚的一本教程,厚到可以用来当凶器的那种。所以错误不少啊,这里或许不是完整版本的勘误。如果读者可以自行发现错误,这也是学习和成长的一部分,非常值得鼓励和敬佩!
第1章:
1. P6的1.5节标题上面一行“非托管(unmanaged code)代码”应该为“非托管代码(unmanaged code)”。
2. P20最后一处代码段上面的一行行括号内的full qualied name拼写错误,应为full qualified name。
3. P21第1行的“但c# using关键字能够减少了按键次数”,应去掉“了”。1.15节下面第3行System.Windows.Form应为System.Windows.Forms。
4. P23第1行“isdasm.exse还有更多的选项”中的exse拼写错误,应为exe。
第2章:
5. P28图2-1的图题“.TestApp”改为“TestApp”。
6. P30倒数第7行“……响应文件里”后面应加上“列出的”。
7. P44倒数第2行的“从……里拖入一个新的类到…..上”中的“拖入”应该改为“拖”。
8. P47第4行“更多相关信息”后加上“时”。
第3章:
新增:P56最下面的超链接的最后应该是html,多了一个h
9. P57的3.4节标题下的第1行“实例应用程序”应改为“示例应用程序”。第2行的“将早期的实例只使用CUI”改为“将早期的示例限制为只使用CUI”。
10. P59倒数第1,2行(表中)的“标记”、“表示”应为“标志”。
11. P59表格后第1行翻译错误,应为“给定的占位符值以冒号为标记,将这些字符作为后缀(例如……”。
补充 P60 表格第四行应译为(比对最新英文版本):受保护的项不能直接从对象变量进行访问,除非是在定义 它的类内部或是在派生类内。
第5章:
12. P149第1处代码段后面的第1行“new指令”漏字,应为“newobj”。
13. P149第1处代码段后面的第4行括号注释应整体前移,紧跟被注释词的后面。倒数第6行“第一个法则”应改为“下一个法则”。本页项目符号后的“法则1”以及P155的“法则2”、P158“法则3”都改为“法则”。
14. P150第12行“代表每一个堆上可达到的对象”应该改为“表示堆上每一个可达到的对象”。
15. P153第1处代码段结束后第1段末尾错误,谈到调用的是方法,而不是对象。应该在段末句号前(在“正在被销毁对象”后)加上“上的方法”。
第6章:
16. P162倒数第7行 “难以预期的bug”,“预期”应为“预料”。
17. P163代码段结束后的第3行“定义良好的包”应为“定义明确的包”。对应well-defined。
18. P168的6.4节标题以上的倒数第3行“大多数情冲况下”错误,应去掉“冲”字。6.4节标题以下的第2行“然而,如表6-1所示。Exception类还会提供……”,其中的逗号应为句号。
19. P170倒数第2行括号内的“默认非空”改为“默认为空”。
20. P175第1处代码段结束后的第二行 “假定读者将之前的异常捕获逻辑修改为在CarIsDeadException与ArgumentOutOfRangeException之前添加试图处理所有异常的通用异常System.Exception,”
正确的应该是“假设我们修改之前的逻辑来增加另外一个catch作用域,它会尝试通过捕获一个普通的System.Exception 来处理包括CarIsDeadException 和ArgumentOutOfRangeException在内的所有异常,”
21. P177第1处代码段注释中“如果读者也可以根据需要自由地引发另外一个不同的异常”不通顺,去掉“如果”。
22. P178倒数第2行“……可以通过悬停鼠标光标在代码窗口的成员名称上,这时可以浏览……的列表”,把 “这时可以”改为“来”。
第7章:
23. P182的7.2节上面倒数第2行“形层次结构”前少了“图”,7.2节下面第3行“编译器会自System.Object”改为“C#编译器会自动加上对System.Object的继承。
24. P195第1处代码段结束后第1、2行“yield 返回”应为“yield return”。
25. P199图题下的第2行:“需要建立一个新的类型以传入每个引用类型成员变量的说明”改为“需要建立一个考虑了每个引用类型成员变量的新的类型”。
26. P201的7.13.1节下的第1行“……用字母作为排序算法……”,其中“字母”应为“昵称”。
27. P202的7.13.2节下面第2行“添加了一个静态只读属性SortByPetName()”,应去掉括号。
第9章:
28. P238第2处代码段结束后的第1行“使用this关键字使索引器看起来就像其他任何C#属性声明一样”翻译错误。应该说“除了使用this关键字以外,索引器看上去和任何其他C#属性声明差不多”。
29. P242倒数第1个代码段的上面第2行“这些简写赋值运算符会被自动具有相应的新功能”去掉“被”。
30. P243第2个代码段中的注释“向传入的Point加1”、“向传入的Point减1”,“向”字不妥,可改为“将”。
31. P247倒数第1行中“必需执行显式转换”应为“必须……”
下面是我补充的错误:
P257 第二行代码 "Address of myInt",应该是Address of ptrToMyInt即ptrToMyInt指针的地址(原作者错误,第4版电子版中仍未更正)
不过根据原书的意思应该是要输出myInt的地址,可以使用下面的两种方法:
Console.WriteLine("Value of ptrtoMyInt:{0:X}",(int)ptrToMyInt);
Console.WriteLine("Address of myInt:{0:X}",(int) &myInt);
//上面的两行代码,前一行输出ptrToMyInt指针的值,也就是myInt变量的地址;后一行输出myInt
变量地址的值;两个值是一致的。
P271 最后一行代码 b1后面少了个"," (印刷错误)
P272 第三行和最后一行代码 typeof(T)后面少了个"," (印刷错误)
P272 图10-1下的代码遗漏了语句结束的分号等其他符号
发现很多页面代码都遗漏了语句结束的分号和其他符号(对照第4版的电子版中没有此问题)
以后不再重复说明这个问题
第10章:
32. P276的10.6.1节下的第1行的 “除了添加命名有独特的公开方法”中多了个“有”。
33. P277表中第6行(Where T:new()的第二行)“如泛型类型必须创建一个类型参数的实例”中“如”应为“如果”。
第11章:
34. P290图11-4中(右上)图字“Type Metadata”改为“类型元数据”。
35. P291第3行和P295图11-9上面第4行“名为名为……”均多了一个“名为”。
36. P300第1处夹线栏里面,以及夹线栏上面两行中的“*.Netmodules”应去掉后面的“s”。
37. P301夹线栏里(第一行)“被请求的程序集复制”,其中的“复制”应为“副本”。
38. P305第5行“COMGUID”应为“COM GUID”。
39. P310倒数第9行“.NETF”改为“.NET下”。
40. P312第2行“如果想要CLR加载一个不同于程序清单中的共享程序集版本”,改为“……清单中的版本的共享程序集版本”。
41. P315第1个项目符号后(页面第三段后)“含有重定向指令*.config或者*.xml文件的位置”,指令后少了“的”。
42. P317倒数第1行“操作”应为“操作符”。
第12章:
43. P321第1个代码段上面的第1行“TypeDef编号是按照C#编译器处理文件的顺序进行的:)”,末尾冒号和右括号互换位置。
44. P324表以上第5行“通过编程得到与通过ildasm.exe中显示的相同的元数据信息”,其中多了个“中”。
45. P337夹线栏里第2行“实体类”应为“整个类”。
46. P346的12.13.4节下的第2行“WindowsOpen”应为“Windows Open”。
47. P348第1行代码段中的英文注释改为“显示公司信息”。倒数第4行“那里”应为“哪里”,倒数第6行“健全”改为“健壮”。
第13章:
48. 353的13.2.3节下面的第1行“这组线程通过Process石成金”最后3个字多余。
49. P355第1处代码段结束后第2行“(ProcessMainpulator)”应放在上一行的“控制台程序”后面。
50. P363的13.4.3节的标题下的第3行“SportsCarTS”应为“SportsCar”。
第14章:
51. P375的14.4.3节标题下的第5行“……参数输入被传入……”,应为“输入参数被传入……”。
52. P376代码段中的注释“获取消息对象,并类型成string”,其中“类型”改为“将类型转换”。本页图下面第1行“来创建此线程中自动处理”改为“来自动创建此线程以处理”。
53. P381 夹线栏上面一行的“多线程简单地让多个线程能够分摊程序的工作量而已”,其中“简单地”应为“只是”。
54. P383的14.8节下面的第2行“包含大量线程”,应为“包含大量次线程”。
55. P387第2个文字段第1行“既然使用lock关键字比起使用System.Threading.Monitor类型代码更少”改为“既然使用lock关键字和使用System.Threading.Monitor类型相比,需要的代码更少”。
56. P388的14.8.4节下的第3行“在13章里,要想对象不被在上下文边界中移动”应为“在第13章里,要想对象在上下文边界中不被移动”。14.9节标题下第3行“可以使用System.Threading.Timer类型和其相关的TimerCallback委托”改为“……类型和与其相关的……”。
第15章:
57. P393第8行“本质上不同的语义区别”去掉“不同”。15.2.1节标题下的第3行“CIL指令语法上是使用一个点(.)的前缀来表示”,其中多了个“是”。
58. P402表头“指示”应为“指令”。(已更正)
59. P403表中第5行“这几个特性是用来指令CLR如何为成员分配内存的”,其中的“指令”应为“指示”(应该是:这几个特性是用来指示)。
60. P408第1个表格中倒数第5、6行“beq用于表示如果相等就中止到代码标签bgt用于表示如果大于就中止到代码标签”,其中bgt前少了分号。第2个表中第3行“变化形势”应为“变化形式”。第2个表结束后的第1行“显示”应为“显式”。
61. P408第2个表结束后的第4行“用来弹出当前的值到一个虚拟执行栈中”应该为“从一个虚拟执行栈中弹出当前的值”。
62. P408第2个表结束后的第4行“用来弹出当前的值到一个虚拟执行栈中”应该为“从一个虚拟执行栈中弹出当前的值”。
63. P409最后一行注释“加载常量4到类型i4 int32的简写”,应为“加载常量4到类型i4(int32的简写)”。
64. P413倒数第2行“实际上下载的是传入的”,其中的“下载”应为“加载”。同样, P415第1处代码段中的第1个注释“存储并下载引用”,应为“ 存储并加载引用”。
65. P415倒数第8行“写作原始CIL代码”应为“编写……”。
66. P423夹线栏上面第2行“希望这章能够加深读者对.NET类型系统和以及CIL语法和语义的理解”,其中多了“和”。
第16章:
67. P446倒数第1行末尾句号前面加上“(如图16-10所示)”。
第17章:
68. P450图上面第5行“这个数可值任意地赋给对象图中的成员”不通顺。可将“值”去掉或“可”与“值”调换位置。
69. P451的3级标题上的倒数第3行(本页倒数第3段的倒数第三行)“实际上,对象图中的所有对象标上[Serializable]特性。”在“对象”后应加上“必须”。
70. P453倒数第11行(倒数第二段的第二行)“因此也不纪录类型完整的修饰名称”,应为“因此也不记录类型的完全限定名”。
71. P457第2行“将在运行时收到InvalidOperation Exception”,英文中间应没有空格(已更正)。
72. 原稿P458的17.7节下第2行“单个的System.Object”改为“一个……”。本页最后一处代码段上面的1行末“JamesBoundCars”末尾的s应去掉。
73. P460表中第4行“定义一个可能在指定流中丢失的域”,其中的“域”应为“字段”。
74. P462第一个文字段第3行“一定要‘使用’System.Runtime.球队Serialization命名空间”中多了“球队”两字。
第19章:
75. P507第1段文字第1句“可以想见”应为“可以想象”。
76. P511倒数第3行“那个键被按下”,其中的“那”应该为“哪”。
77. P512最后一个表中第1行“无论何时窗体被激活时就会发生”中删除“无论何时“。表结束后的第2行“Coca”应为“Cocoa”。
78. P513倒数第1处代码段上面的倒数第1行“以确保用户使用……终止程序”改为“以确保用户的确想要使用……终止程序”。
第22章:
79. P635倒数第2行“字符串”前少了“连接”。
80. P637的3级标题下的第2行(22.10.2下的第2行)“连接字符串构造器对象”中“器”应为“函数”。
81. P650第1个表格结束后的第1句话“实现某些前面属性提到的那些功能”,应去掉“某些,“那些”改为“某些”。本页第2个表格倒数第2、5条线多余。。
82. P652第2行“我们来继续前面SimpleDataSet那个项目(并且为了演示怎么使用DataColumn)来为Inventory表建立列”,改为“我们来继续前面那个SimpleDataSet项目(并且演示怎么使用DataColumn),假定为Inventory表建立列”。
83. P652的第1个3级标题下的第4行(22.18.2下的第5行)“Data Column”中间的空格应去掉。
84. P657第3行右括号后面的“和”改为“,作为”。
第23章:
新增:P678 第四段 第5行 D后漏了两个字母NS。
85. P681第2行“通过/parth”应为“通过/path”。
86. P688第1个项目符号后的句子“ASP.NET页面是1.x提供了名为……”其中 “页面是”多余。
87. P702第1个表中倒数第1、3行以及下一页第3行“访问允许…….请求/对象”应为“允许访问……”。
88. P704的23.14节上面第2行,即代码中注释“DataSet并且缓存它”,句前少了“填充”。
89. P717的23.20.2节下的第2行“当创建了这个新的站点时”改为“这个新的站点创建好后”;还有第5行 “需要放置在……作用域内”应该是“由……作用域代替”。
90. P722第2行“插入到当前项目。”前面加上“将文件”。本页项目符号后的“单一的……控件”应为“一个……”。
91. P724第2个表中第4行“获取或设置指明客户端验证是否启动”末尾漏了中心词,补上“的值”。
92. P726倒数第1处夹线栏上面的第3行、P727夹线栏上面第5行“验证控件”应该为“验证程序”,。
第27章:
93. P797夹线栏内第2行“参见由即将出版的Adam Nathan所著的……”,应为“参见即将出版的由Adam Nathan所著的……”。
第29章:
94. P870倒数第3行“创建一个代码我们类型的WF实例”,其中的“代码”应为“代表”。
第30章: 原稿P899最后一个项目符号结束后的一段话排版有误,第2行应接排。
第31章:
95. P918第1处代码段结束后的第2行行:“不管怎样记住”,应为“不管怎样,记住”。
96. P916~~P919以及P931出现的“代理”都应改为“委托”。
- //下面是由CSDN网友提供的,供大家参考
- P63 关于常量例子不充分(诗剑书生ID:axman提供)
- P64/65 readonly描述不准确(诗剑书生ID:axman提供)
- P92 Equals实现问题(诗剑书生ID:axman提供)
- P142 引用类型转换的问题(诗剑书生ID:axman提供)
- P161 关键全局变量的改变的问题(诗剑书生ID:axman提供)
- P197/199 Clone的实现(诗剑书生ID:axman提供)
- P213同步Invoke()调用问题(诗剑书生ID:axman提供)
- P267使用泛型后加入值类型的问题(诗剑书生ID:axman提供)
- 鸣谢见最后
- ---
- P63 关于常量例子不充分
- 下面那个图说明
- public const string BestNbaTeam = "timberwolves";
- 是常量的例子。
- 编译后成.field public static literal string BestNbaTeam = "timberwolves"根本说明不了它是常量,应该加上一句调用:
- Console.WriteLine(BestNbaTeam);
- 编译后是 ldstr "timberwolves"而不是ldsfld string className::BestNbaTeam这才能说明问题.
- ---
- P64/65 readonly描述不准确
- 不是不能改变而是一经赋值就不能重新赋值,简单说变量只能永远指向最初的那个对象.不能重新赋值,但对象本身可以改变.
- static readonly StringBuilder sb = new StringBuilder("axman");
- static void Main(string[] args)
- {
- Console.WriteLine(sb.ToString());
- sb.Append(' is a great person!');
- Console.WriteLine(sb.ToString());
- Console.ReadLine();
- }
- 你完全可以改变sb指向的对象的内容.但你不能再把它指向另一个对象.
- static void Main(string[] args)
- {
- sb = new new StringBuilder("axman1");
- Console.ReadLine();
- }
- 其实这和java中final变量的意思是一样的.
- ---
- P92 Equals实现问题()
- 92页的Equals实现还是存在重大设计性错误。作者对陷井并不了解。
- 按作者的想法实现下面的类,看看是什么结果?
- a==b,但b!=a
- class Person {
- public string name;
- public int age;
- public Person(string name,int age) {
- this.name = name;
- this.age = age;
- }
- public override bool Equals(object obj)
- {
- if (obj != null && obj is Person) {
- Person temp = (Person)obj;
- if (temp.name == this.name && temp.age == this.age) return true;
- }
- return false;
- }
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
- }
- class ChinaPerson : Person {
- public string city;
- public ChinaPerson(string name, int age,string city) : base(name,age)
- {
- this.city = city;
- }
- public override bool Equals(object obj)
- {
- if (obj != null && obj is ChinaPerson)
- {
- ChinaPerson temp = (ChinaPerson)obj;
- if (temp.name == this.name && temp.age == this.age && temp.city == this.city) return true;
- }
- return false;
- }
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
- }
- static class Program
- {
- static void Main(string[] args)
- {
- ChinaPerson cp = new ChinaPerson('axman', 100, 'bj');
- Person p = new Person('axman',100);
- Console.WriteLine(p.Equals(cp));
- Console.WriteLine(cp.Equals(p));
- Console.ReadLine();
- }
- }
- ---
- P142 引用类型转换的问题
- 142页对于引用类型转换,仍然采用了笨拙的方法,浪费性能。
- if(e is Manager){
- ((Manager)e).XXX;
- }
- 这样的调用首先e is Manager要做isinst操作来测试类型,然后再调用castclass来强行转换。
- 而Manager m = e as Manager只需做isinst,如果返回真就直接用stloc.x操作将e的地址赋给了m.
- 后面我们只需判断if(m == null)或m!=null来操作m就行了。稍有水平的 .NET程序员应该坚决避免先isinst再
- cstaclass这种耗时的操作。
- 有人说"这里"只是为了说明问题举的简单的例子,没有必要"刻意"表现性能,那么看223页,作者在"刻意"下仍然不
- 知道直接用as 来简化操作.
- ---
- P161 关键全局变量的改变的问题
- 第161页 对表示状态的关键全局变量的改变竟然没有同步,disposed = true;完全是一个初级程序员的思维,任何
- 两个线程同时运行都有可能使这个"正式的可处置模式"失败.
- ---
- 首先,197中.
- public object Clone(){return new Point(this.x,this.y);}
- 这种行为本身就是一种非常搞笑的,别说实现得好不好,有这种思维就是一个愚蠢的行为.
- clone的目的是什么?就是要通过"复制"而不是new 的方式来生成一个和已有对象状态一致的对象.如果用new 来
- 实现clone,那么调用者自己不会new ?你new的动作比调用者萧洒?由你new出来的对象比调用者自己new出来的
- 对象更好控制?既然是new出来的那为什么没事找事加上一个clone?所以这种实现本身就违反clone的意义.且不说
- 实现得好不好了.
- 我们再看199页所谓的深复制,Point的成员变量PointDescription有一个成员变量petName,所以作者new 了一个
- PointDescription又复制了petName.如果PointDescription的成员变量又包含成成员变量,这样多级的引用呢?按
- 作者实现思路如何递归并反射进行赋值?如果是私有成员变量你还能给它赋值?这样的代码能实现真正的深复制?
- 我就想不通一般普通程序员都知道的用序列化实现对象的深复制,到了大师手里就这么难呢?
- public object Clone() {
- BinaryFormatter bf = new BinaryFormatter();
- MemoryStream ms = new MemoryStream();
- bf.Serialize(ms, this);
- ms = new MemoryStream(ms.ToArray());
- return bf.Deserialize(ms);
- }
- 这样一段对所有要实现深复制的对象都适用的代码难道不比那种要手工不断递归赋值也不能完全深复制的代码强?
- 我们要做的仅仅是在类前面加一段 [Serializable]而已.(不要钻牛角尖说有些字段不可序列化,那样的情况先反序列化得到一个新对象后再手工生成不可序列化字段也比递归反射再一个一个赋值要高
- 明且完全得多)
- ---
- P213同步Invoke()调用问题
- 第213页最下面"奇怪的是,同步Invoke()不能直接在C#中调用",我奇怪的是我为什么有直接调用?RP问题?
- delegate void Test();
- class Program
- {
- static void t() {
- Console.WriteLine("Axman!");
- }
- static void Main(string[] args)
- {
- Test t1 = new Test(t);
- t1.Invoke();
- Console.ReadLine();
- }
- }
- ---
- P267使用泛型后加入值类型的问题
- 使用泛型后加入值类型后,作者说从编译后的IL看到没有Boxing和Unboxing操作,虽然结果巧合是正确的,
- 但这个说明是完全错误的,假如泛型也是完全基于堆来实现,List<int>对象的Add方法完全可以接收一个值类型后
- 在方法类Boxing,获取方法完全可以在方法内UnBoxing后再返回值类型.仅从编译后那几行IL不可能说明泛型没有
- 执行Boxing和Unboing操作.真正说明问题的是显示List<int>对象的_items成员,这个成员是根据传入的类型生成
- 的该类型数组,List<int> 时就是int[ ] 数组来存放Add加入的数据,这才可以说明没有发生Boxing和Unboing.
- ---
- ---
- 鸣谢信息:
- 感谢 诗剑书生 提供的资料
- 原文链接http://blog.csdn.net/axman/archive/2008/03/05/2149150.aspx