天天看點

C#與.NET 3.0 進階程式設計(特别版) 勘誤表

這是我第一本參與翻譯的書,下面是勘誤表。非常厚的一本教程,厚到可以用來當兇器的那種。 是以錯誤不少啊,這裡或許不是完整版本的勘誤。如果讀者可以自行發現錯誤,這也是學習和成長的一部分,非常值得鼓勵和敬佩!

第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出現的“代理”都應改為“委托”。

P937第7、8行“但如果你對衆多的 XML技術(XPath,XQuery,XSLT,DOM,SAX等)不是很精通。那麼XML程式設計從一開始就非常枯燥、 煩瑣 和複雜,”括号内的逗号應為頓号,括号外的逗号和句号應互換

  1. //下面是由CSDN網友提供的,供大家參考
  2. P63 關于常量例子不充分(詩劍書生ID:axman提供)
  3. P64/65 readonly描述不準确(詩劍書生ID:axman提供)
  4. P92 Equals實作問題(詩劍書生ID:axman提供)
  5. P142 引用類型轉換的問題(詩劍書生ID:axman提供)
  6. P161 關鍵全局變量的改變的問題(詩劍書生ID:axman提供)
  7. P197/199 Clone的實作(詩劍書生ID:axman提供)
  8. P213同步Invoke()調用問題(詩劍書生ID:axman提供)
  9. P267使用泛型後加入值類型的問題(詩劍書生ID:axman提供)
  10. 鳴謝見最後
  11. ---
  12. P63 關于常量例子不充分
  13. 下面那個圖說明
  14. public const string BestNbaTeam = "timberwolves";
  15. 是常量的例子。
  16. 編譯後成.field public static literal string BestNbaTeam = "timberwolves"根本說明不了它是常量,應該加上一句調用:
  17. Console.WriteLine(BestNbaTeam);
  18. 編譯後是 ldstr "timberwolves"而不是ldsfld string className::BestNbaTeam這才能說明問題.
  19. ---
  20. P64/65 readonly描述不準确
  21. 不是不能改變而是一經指派就不能重新指派,簡單說變量隻能永遠指向最初的那個對象.不能重新指派,但對象本身可以改變.
  22. static readonly StringBuilder sb = new StringBuilder("axman");
  23. static void Main(string[] args)
  24. {
  25. Console.WriteLine(sb.ToString());
  26. sb.Append(' is a great person!');
  27. Console.WriteLine(sb.ToString());
  28. Console.ReadLine();
  29. }
  30. 你完全可以改變sb指向的對象的内容.但你不能再把它指向另一個對象.
  31. static void Main(string[] args)
  32. {
  33. sb = new new StringBuilder("axman1");
  34. Console.ReadLine();
  35. }
  36. 其實這和java中final變量的意思是一樣的. 
  37. ---
  38. P92 Equals實作問題()
  39. 92頁的Equals實作還是存在重大設計性錯誤。作者對陷井并不了解。
  40. 按作者的想法實作下面的類,看看是什麼結果?
  41. a==b,但b!=a
  42. class Person {
  43. public string name;
  44. public int age;
  45. public Person(string name,int age) {
  46. this.name = name;
  47. this.age = age;
  48. }
  49. public override bool Equals(object obj)
  50. {
  51. if (obj != null && obj is Person) {
  52. Person temp = (Person)obj;
  53. if (temp.name == this.name && temp.age == this.age) return true;
  54. }
  55. return false;
  56. }
  57. public override int GetHashCode()
  58. {
  59. return base.GetHashCode();
  60. }
  61. }
  62. class ChinaPerson : Person { 
  63. public string city;
  64. public ChinaPerson(string name, int age,string city) : base(name,age)
  65. {
  66. this.city = city;
  67. }
  68. public override bool Equals(object obj)
  69. {
  70. if (obj != null && obj is ChinaPerson)
  71. {
  72. ChinaPerson temp = (ChinaPerson)obj;
  73. if (temp.name == this.name && temp.age == this.age && temp.city == this.city) return true;
  74. }
  75. return false;
  76. }
  77. public override int GetHashCode()
  78. {
  79. return base.GetHashCode();
  80. }
  81. }
  82. static class Program
  83. {
  84. static void Main(string[] args)
  85. {
  86. ChinaPerson cp = new ChinaPerson('axman', 100, 'bj');
  87. Person p = new Person('axman',100);
  88. Console.WriteLine(p.Equals(cp));
  89. Console.WriteLine(cp.Equals(p));
  90. Console.ReadLine();
  91. }
  92. }
  93. ---
  94. P142 引用類型轉換的問題
  95. 142頁對于引用類型轉換,仍然采用了笨拙的方法,浪費性能。
  96. if(e is Manager){
  97. ((Manager)e).XXX;
  98. }
  99. 這樣的調用首先e is Manager要做isinst操作來測試類型,然後再調用castclass來強行轉換。
  100. 而Manager m = e as Manager隻需做isinst,如果傳回真就直接用stloc.x操作将e的位址賦給了m. 
  101. 後面我們隻需判斷if(m == null)或m!=null來操作m就行了。稍有水準的 .NET程式員應該堅決避免先isinst再
  102. cstaclass這種耗時的操作。
  103. 有人說"這裡"隻是為了說明問題舉的簡單的例子,沒有必要"刻意"表現性能,那麼看223頁,作者在"刻意"下仍然不
  104. 知道直接用as 來簡化操作.
  105. ---
  106. P161 關鍵全局變量的改變的問題
  107. 第161頁 對表示狀态的關鍵全局變量的改變竟然沒有同步,disposed = true;完全是一個初級程式員的思維,任何
  108. 兩個線程同時運作都有可能使這個"正式的可處置模式"失敗.
  109. ---
  110. 首先,197中.
  111. public object Clone(){return new Point(this.x,this.y);}
  112. 這種行為本身就是一種非常搞笑的,别說實作得好不好,有這種思維就是一個愚蠢的行為.
  113. clone的目的是什麼?就是要通過"複制"而不是new 的方式來生成一個和已有對象狀态一緻的對象.如果用new 來
  114. 實作clone,那麼調用者自己不會new ?你new的動作比調用者蕭灑?由你new出來的對象比調用者自己new出來的
  115. 對象更好控制?既然是new出來的那為什麼沒事找事加上一個clone?是以這種實作本身就違反clone的意義.且不說
  116. 實作得好不好了.
  117. 我們再看199頁所謂的深複制,Point的成員變量PointDescription有一個成員變量petName,是以作者new 了一個
  118. PointDescription又複制了petName.如果PointDescription的成員變量又包含成成員變量,這樣多級的引用呢?按
  119. 作者實作思路如何遞歸并反射進行指派?如果是私有成員變量你還能給它指派?這樣的代碼能實作真正的深複制?
  120. 我就想不通一般普通程式員都知道的用序列化實作對象的深複制,到了大師手裡就這麼難呢?
  121.         public object Clone() {
  122.             BinaryFormatter bf = new BinaryFormatter();
  123.             MemoryStream ms = new MemoryStream();
  124.             bf.Serialize(ms, this);
  125.             ms = new MemoryStream(ms.ToArray());
  126.             return bf.Deserialize(ms);
  127.         }
  128. 這樣一段對所有要實作深複制的對象都适用的代碼難道不比那種要手工不斷遞歸指派也不能完全深複制的代碼強?
  129. 我們要做的僅僅是在類前面加一段    [Serializable]而已.(不要鑽牛角尖說有些字段不可序列化,那樣的情況先反序列化得到一個新對象後再手工生成不可序列化字段也比遞歸反射再一個一個指派要高
  130. 明且完全得多)
  131. ---
  132. P213同步Invoke()調用問題
  133. 第213頁最下面"奇怪的是,同步Invoke()不能直接在C#中調用",我奇怪的是我為什麼有直接調用?RP問題?
  134.     delegate void Test();
  135.     class Program
  136.     {
  137.         static void t() {
  138.             Console.WriteLine("Axman!");
  139.         }
  140.         static void Main(string[] args)
  141.         {
  142.             Test t1 = new Test(t);
  143.             t1.Invoke();
  144.             Console.ReadLine();
  145.          }
  146.     }
  147. ---
  148. P267使用泛型後加入值類型的問題
  149. 使用泛型後加入值類型後,作者說從編譯後的IL看到沒有Boxing和Unboxing操作,雖然結果巧合是正确的,
  150. 但這個說明是完全錯誤的,假如泛型也是完全基于堆來實作,List<int>對象的Add方法完全可以接收一個值類型後
  151. 在方法類Boxing,擷取方法完全可以在方法内UnBoxing後再傳回值類型.僅從編譯後那幾行IL不可能說明泛型沒有
  152. 執行Boxing和Unboing操作.真正說明問題的是顯示List<int>對象的_items成員,這個成員是根據傳入的類型生成
  153. 的該類型數組,List<int> 時就是int[ ] 數組來存放Add加入的資料,這才可以說明沒有發生Boxing和Unboing.
  154. ---
  155. ---
  156. 鳴謝資訊:
  157. 感謝 詩劍書生 提供的資料
  158. 原文連結http://blog.csdn.net/axman/archive/2008/03/05/2149150.aspx