C# Essentials by Ben Albahari, Peter Drayton & Brad Merrill 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. If you have any error reports or technical questions, you can send them to booktech@oreilly.com. (Please specify the printing date of your copy.) This page was last updated March 11, 2002. 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 UNCONFIRMED errors and comments from readers: {8} second code sample: The following line from the code sample is missing a semi-colon: short z =(short)x // explicit conversion to 2-byte integer It should be: short z =(short)x; // explicit conversion to 2-byte integer ?10? middle of the page; the text says, "15 to 16 significant figures" without comment - if this matters, it should be clarified (11) The second sentence in the first paragraph reads: ...because the lowest and highest possible values of a float or double exceed those of an int, unit, or long's lowest of highest value. There are two problems here: 1. "unit" is not an integral type; this should be "uint" (for Unsigned INTeger). 2. "lowest of highest" is not correct. Do you mean "lowest and highest?" (11) first code sample: The code sample contains the following line: float x = 9.53f * strenngtgth - offset It looks like "strenngtgth" should be "strength". ?11? top half of page; the text says, "28 to 29 significant figures" without comment - if this matters, it should be clarified (11) second last line; s/Char/char (the c# type is char) (12) second to last paragraph; The text is ungrammatical. Instead of "on most ...can work", it should perhaps say, "that most PAs can address" (12) second to last paragraph; the last sentence should read "in an array" or, better, "of an" ?13? bottom of page; '\r' is used without comment in the examples. Does c# need carriage returns (unlike C, VB, ...)? (14) second paragraph; Inconsistency: the terms 'inline' and 'in-line' are used interchangeably. (16) last paragraph; "such as" binds to "class or struct", not "operators" as intended (17) Note at bottom of page; In "of the class object", "object" should be constant width {20} Table 2-2; The last paragraph on page 19 says for table 2-2 "Operators in the same box have the same precedence..." However, table 2-2 is missing the lines for these boxes. This makes reading the table difficult. For example, it's unclear that "And: &&" has a higher precedence than "Or: ||". (23) third paragraph; "to conditionally control" is a split infinitive ?24? first paragraph; The second sentence reads: switch statements can result in cleaner code than if you use multiple if statements, because the controlling is evaluated only once. Is there an expression missing? (24) The last paragraph (which continues on to page 25) is is unclear and specifies "break" rather than "jump statement". [26] last paragraph (before the last code sample): The second sentence is as follows: Although not strictly necessary, all collections leverage this functionality by supporting the IEnumerable and IEnumerable interfaces,... IEnumerable is duplicated in this sentence. So, which two interfaces do all collections support? Also, what does it mean to "support" an interface? Should this be "implement" instead to be more clear? {26} last paragraph; "IEnumerable and IEnumerable" should probably be: "IEnumerable and IEnumerator" [27] break statement; The description does not scan properly. I have changed the first "to" to "from" so that it now reads: "The break statement transfers execution from the enclosing while loop...to the next statement block." Is this a correct interpretation? [32] last paragraph; The code fragment for LocalFile is wrong. 'public LocalFile(string name) : base(name)' will call Location's constructor, not URL's. static void Main() { URL u = new URL(); LocalFile l = new LocalFile(); won't compile because both the URL constructor and the LocalFile constructor require string args. [39] Playing with the C# compiler, I noticed that the following code only generates warnings, not errors. So, it appears that regardless of read-only status, a field can be compiled without ever being assigned. using System; public class ReadOnly { private static readonly int readOnlyStatic; private static int writeableStatic; public static void Main() { Console.WriteLine(readOnlyStatic); Console.WriteLine(writeableStatic); ReadOnly r = new ReadOnly(); r.Foo(); } private readonly int readOnlyInstance; private int writeableInstance; public void Foo() { Console.WriteLine(readOnlyInstance); Console.WriteLine(writeableInstance); } } {41} Near the end of the code example; The authors use the phrase "get and set(throw a dime in the well)" as a source code comment. However, the += statement first fetches and then updates a value, and so this is a wishing well from which you take money before contributing. (51) second code sample: Static constructor is incorrectly labeled "Test". It should be "Test2", so the code sample should now read: class Test2 { public static void Foo() {} static Test2() { Console.WriteLine("Test2 Initialized"); } } Test.Foo(); Test2.Foo(); {60} in the TestEnum class there seems to be absence of casting object[] oa = Enum.GetValues(typeof(Toggle)); should be object[] oa =(object [])Enum.GetValues(typeof(Toggle)); [64] if (args.cancel) in example of Slider; Maybe one more tab is needed for "if(args.cancel)" in set of property Position of Slider. In the book, it looks as if (position != value) { if (Move != NULL) { // if invocation list not empty MoveEventArgs args = new MoveEventArgs(value) Movve(this, args); // fire event if (args.cancel) return } position = value; indentation of if (args.cancel) seems to be wrong and misleading. Right way: if (position != value) { if (Move != NULL) { // if invocation list not empty MoveEventArgs args = new MoveEventArgs(value) Movve(this, args); // fire event if (args.cancel) return; } position = value; (75) Table 2-4 "Error Text"; error manager should be error message [95] The code example: ... // Using IEnumerator: substitute your typename for XXX IEnumerator ie = myc.GetEnumerator(); while (myc.MoveNext()) { XXX item = (XXX)myc.Current; Console.WriteLine(item); ... } is incorrect in two ways. (1) Once the IEnumerator variable ie has been initialized, the rest of the code should be using it instead of myc. (2) The variable myc is not declared anywhere. The code section above the incorrect section declares a MyCollection mcoll, and I believe this is what was actually intended. Here is the same section rewritten to correct these errors: ... // Using IEnumerator: substitute your typename for XXX IEnumerator ie = mcoll.GetEnumerator(); while (ie.MoveNext()) { XXX item = (XXX)ie.Current; Console.WriteLine(item); ... } (99) 2nd paragraph: The last sentence describes the "System.I/O" namespace. It should read the "System.IO" namespace. (104) code example; the current example code using the static *Create(..)* factory method to generate an appropriate concrete subclass of the abstract WebRequest class does not belong to a class *WebRequestFactory*. It belongs to the WebRequest class itself. Therefore, the code should be changed from: // Retrieve the data at the URL with an WebRequest ABC WebRequest req = WebRequestFactory.Create(args[0]); WebResponse resp = req.GetResponse(); to: // Retrieve the data at the URL with an WebRequest ABC WebRequest req = WebRequest.Create(args[0]); WebResponse resp = req.GetResponse(); {160} errata; The errata description of the change made on page 160 is itself incorrect. "twelve-bit has been changed to sixteen-bit" should be "byte" not "bit" in both cases.