Learning C# 2005, 2nd Edition by Jesse Liberty and Brian MacDonald The unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification This page was updated August 1, 2008. UNCONFIRMED errors and comments from readers: [23] next to last paragraph; The first sentence of the paragraph is "As you click on each positioning indicator, a shadow appears ..." It should be "When you drag the mouse pointer onto a positioning indicator, a shadow appears ..." {66} Table 4-2 Logical Operators; First line in Table 4.2 Logical operators (assume x = 5 and y = 7): Name: And Operator: && Given this statement: (x == 3) && (y == 7) This expression evaluates to: False Logic: Both must be true. Logic is wrong: Either or both must be false. {69} The error is in the top algorithm; In the "Learning C# 2005" book by Jesse Liberty & Brian MacDonald, on page 69, there is an error. The error is in the top algorithm. It is missing a closing ")" after "secondsPerMinute". [82,83,84] Nested if Statements section; The Nested If Statements section demonstrates three different ways of representing a temperature contingent program, which is capable of displaying an appropriate message based on the value of a temperature variable. Of the three variations to the supposed same logic, only the latter two demonstrated, share the same logic. To elaborate upon this: FIRST EXAMPLE: Example 5-6 if ( temp <= 32 )//rules out everything that is greater than 32 { if ( temp == 32 )//Equal to else//Less than 32 } SECOND EXAMPLE: Example 5-7 if ( temp < 32 )//rules out anything that is greater than or equal else if ( temp == 32 )//rules out anything that is greater than 32 else //deals with all values greater than 32 THIRD EXAMPLE: Example 5-8 if ( temp < 32 )//rules out everything that is greater than or equal to 32 else//deals with all values greater than or equal to 32 { if ( temp == 32 )//equal to values are dealt here else //greater than 32 values go in this block } Clearly, the logic flow in examples 5-7 and 5-8 follows a congruent path. In the first example (5-6), however, the values greater than 32 are not captured into any branches, which goes against the second last line in the third paragraph on page 83, which states "you could rewrite Example 5-6..." [86] Last line; It is not clarified whether the output displayed towards the bottom on page 86, would correspond to an actual invalid case selection made by the user where the default case comes into play. Otherwise if the author is conveying the output as coming from Example 5-9 (A default statement), it is clearly erroneous because the value of myChoice remains Party.Democrat and hence the output should've been" You voted Democrat. Thank you for voting. [86] last paragraph; I believe that the example 5-9 (A default statement) does not produce the output that you have listed. It should have produced: You have voted Democratic. Perhaps you would have the example you wanted for the execution of the default statement if you added a fourth member to the enum Party (call is "Conservative") and then hard-wire the choice to Party.Conservative instead of Party.Democrat, as you did. ?97? center of page: "The string ends when you press A." the STRING ends? do you mean, "execution ends" or "program ends" or something else? (123) near bottom: "The Time class of Example 7-2 does not define a constructor..." The Time class is the subject of examples 7-1 and 7-3, but not 7-2. {127}middle page; in code snippet: public void SomeMethod(int hour) { this.hour=newHour; } The "newHour" variable should instead be "hour", representing the parameter variable passed in to the method. That's the whole point of the example: to show that the variable and an internal member have the same name, and thus the need for "this" to resolve the ambiguity. {127} the implementation of SetTime methods; this.hour = hour; should be this.hour = newHour; {133} center of page, two occurrences: "The Main() method accesses..." "Main() then creates an instance...." in both cases it's Run() that does it, not Main() (134) On the second to last line; method declaration should be: public void Close() { not public void Dispose() { (164) just before new topic at bottom of page: "...I have typed in the Value > 20 as an example." Minor points but should this be in a different font to distinguish it from the surrounding normal text? also you say "the Value" when of course you really typed "theValue" (no space) as the breakpoint condition. [172] directions to exercise 9-2: "...or download it from this book's web site." I did download the source code, and unless I goofed, there's no source code for chapter 9. (184)middle of page, below code Example 10-5; multidimensional array variable "rectangularArray" is misprinted repeatedly as "rectangularArrayrectangularArray" [200]bottom third; It looks as if the base class and derived class names are mixed up in the code snippet near the bottom of p. 200: "public class MyClass : myOtherClass" Three pages previous to the code snippet, the authors write (on p. 197): "In C#, you create a derived class by adding a colon after the name of the derived class, followed by the name of the base class. . ." But on page 200, we find: "If you create a new class, myOtherClass, that derives from myClass, like this: public class MyClass : MyOtherClass . . ." So, in this (erroneous?) example the base class is on the LEFT side of the colon, not on the right side. {213} Last paragraph; The second example of boxing is incorrect: int myInt = 5; myInt.ToString( ); This will not cause a box in IL. The following code: static void Main( string[ ] args ) { int i = 3; i.ToString( ); } Generates the following IL: .method private hidebysig static void Main(string[] args) cil managed { .entrypoint .maxstack 1 .locals init ( [0] int32 i) L_0000: nop L_0001: ldc.i4.3 L_0002: stloc.0 L_0003: ldloca.s i L_0005: call instance string [mscorlib]System.Int32::ToString() L_000a: pop L_000b: ret } No box. If we add this line: object o = i; we get the following IL: .method private hidebysig static void Main(string[] args) cil managed { .entrypoint .maxstack 1 .locals init ( [0] int32 i, [1] object o) L_0000: nop L_0001: ldc.i4.3 L_0002: stloc.0 L_0003: ldloca.s i L_0005: call instance string [mscorlib]System.Int32::ToString() L_000a: pop L_000b: ldloc.0 L_000c: box int32 L_0011: stloc.1 L_0012: ret } Now the int is boxed. Interestingly, if you'd made the example call GetType instead of ToString, you'd have forced a boxing of the int. This is because Int32 inherits GetType from System.Object. {214} near bottom: "Example 11-5 creates an integer myIntegerVariable and implicitly boxes it..." Isn't this example nearly identical to the example at the bottom of the previous page, where you say "You can, of course, first cast the value type to a reference type" which you seem to imply is a case of EXPLICITLY boxing it...you seem to be doing the same here on page 214, but you call it "implicit"....maybe I'm confused.... (216) 4th bullet, 4th line: "will use the keyword overrides (rather than new)..." For one, the keyword is "override", correct? and for two, shouldn't these be in the font reserved for keywords, as is the keyword "new" earlier in the same bullet? {252} 1/3 of the way down: "...and then casts the Document first to be of type IStorable, then to be of type ILoggedCompressible." I don't see where you're casting it to be of type IStorable...either I'm misunderstanding, or there's something amiss here..... {256} middle of the page; public class Document : Note should implement interface IStorable public class Document : Note, IStorable {257-260} There are what appear to be many typos here in the code, starting in the center of 257 where the if checks if the cast worked, but it checks "isStorable" for null instead of "isStorable2", then at the bottom of 258 and continuing on into the discussion of the code which contains 16 apparent discrepancies with the code in the continuous source code example 13-5. (271) code in center of page: Doesn't lbt[5] = "Hello World" need a semicolon? (275) 4th paragraph; While analyzing Example 14-2, page 275, 4th paragraph "It gets back an index and uses that index to index into myStrings:" Should be: "It gets back an index and uses that index to indext into strings: Similarly (3 lines down): "myStrings[FindString(index)] = value;" Should be: "strings[FindString(index)] = value;" (282) Last line of the program output; The last line of the main function is Console.WriteLine( "empList.Capacity: {0}", empList.Capacity ); The output shows up as "empArray.Capacity: 8" intead of "empList.Capacity: 8". (304) first verbatim string: They aren't really equivalent, cuz string s2 has an extra space right before the word "My" ! (310) near top, typos: "s3 goes on referring to the original string...." "if you later write s3="Goodbye"..... I think you're referring to s1 and s2, so where you say s3 there, I think you mean s2.... {312-13} code and output: It appears there's a little confusion between s3 and s5 going on. I'm referring specifically to lines 2 and 3 of the output, and the > code that produces them: s3 is NOT 4 characters long...s5 is... you're showing the length of s5, not s3...also, since you don't mention what string you're referring to when you say that the "5th character is r", it's implied you still mean s3, but we already know it's only 4 characters long, so it can't have a fifth character.....you really mean s5.... {319} from "Start the foreach loop..." through the end of the topic: It appears your discussion refers to a variation on the code which will be developed next with the StringBuilder class...you refer to the variable "output", as if it occurs in the previous code. Only it doesn't. [346] Qu 16.2; The answer to 16.2 does not appear to correspond to the question, ie there is no error of type "CustomerCatError" and CatManager does not have the additional method call. Exercise 16-2. Modify Exercise 16-1 so that it does not throw an error. Create a custom error type CustomCatError that derives from System.Exception, and create a handler for it. Add a method to CatManager that checks the cat's age, and throws an error of type CustomCatError if the age is less than or equal to 0, with an appropriate message. (359) last 3 lines of code: public readonly int Hour, Minute, Second; Shouldn't those all be lacking their initial capitalization? I checked the code online, and they are lowercase there. (386) 2/3 thru the page: private void GetSubDireoctoryNodes( clearly should be private void GetSubDirectoryNodes( {460} solution to Question 10-5: Employee[] myEmpArray = new Employee[3] = { moe, larry, curley }; I think the second = produces an error, and should be absent, right?