Head First C# by Andrew Stellman, Jennifer Greene This errata page lists errors fixed in the September 15, 2008 reprinting. If you have technical questions or error reports, you can send them to booktech@oreilly.com. Please specify the printing date of your copy. This page was updated August 26, 2008. 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 Confirmed errors: (xxviiii) In the header and first line of body text change ÒWindows Presentation FrameworkÓ to ÒWindows Presentation FoundationÓ. (26) Change the headline from ÒDiagram your data so your application to access itÓ to ÒDiagram your dataÓ And replace the top paragraph of body text with: ÒThe Visual Studio IDE is built to work with databases, and it comes with a lot of built-in tools that help you when youÕre handling a lot of data. One of the most powerful tools you have is the database diagram, which you can use to view and edit complex relationships between the tables in your database. So letÕs go ahead and build a database diagram for your database.Ó (27) In the sidebar, change the second sentence from this: ÒThe IDE then uses the database diagram to auto generate code to work with your database.Ó To this: ÒThe IDE will read your database and build a database diagram for you automatically.Ó (44) Remove the word ÒjustÓ from the bottom annotation (ÒThe Properties window in the IDE is a really easy wayÉÓ). {55} Ð sidebar (ÒEvery C# program must haveÉÓ) Add an annotation pointing down at this sidebar that says: ÒTechnically, a program can have more than one Main() method, and you can tell C# which one is the entry pointÉ but you wonÕt need to do that now.Ó {69} top annotation; This line checks someValue to see if it's less than 3 ......... should be This line checks someValue to see if it equals 3 ......... Change the top annotation from Òto see if itÕs less than 3Ó to Òto see if itÕs equal to 3Ó (73) Change this: ÒYes, there are a few namespaces youÕre not allowed to use.Ó To this: ÒTechnically there arenÕt any namespaces youÕre not allowed to use. But there are several namespaces that .NET uses, and itÕs a bad idea to use them yourself.Ó {73} Change this: and System.Math, which has mathematical functions. To this: and System.IO, which lets you work with files and data streams. (76) Change the second annotation to: ÒThis line tells the program to stop your loop momentarily and do the other things it needs to do, like refresh the form, check for mouse clicks, etc. Try taking out this line and seeing what happens. The form doesnÕt redraw itself, because itÕs waiting until the loop is done before it deals with those events.Ó Add another annotation pointing up at it: ÒLater on in the book, youÕll learn about a better way to let your programs do more than one thing at a time! But for now, use Application.DoEvents() to make sure your form stays responsive while itÕs in a loop.Ó (89) second paragraph under step 2, second sentence "repated" should be "repeated" (89) "... a number of its numberOfTimes parameter." change to: "... a number for its numberOfTimes parameter." {93} last paragraph In the text: search the entire project for the text ñbutton 1 = newî. remove the space in "button 1" -- it should be "button1 = new". {102}code example for bulleted point #1; The current example says: int t = m.chkTemp(); if (t > 160) { T obj = new T(); tb.clsTrpV(2); ics.Fill(); ics.Vent(); m.airsyschk(); } The line with the tb.clsTrpV(2) I believe should be obj.clsTrpV(2) or the line before should be changed to T tb = new T(); which is a better solution since tb could be short for turbine so that tb.clsTrpV(2) is for "close the trip throttle valve on turbine #2" which is the first step in the specification manual example at the bottom of page 102. In the code block under step 1, changed the third line: T obj = new T(); To this: T tb = new T(); {110} last line; The two methods used in the Guy class are : GiveCash() ReceiveCash() In that line ( and in the pictures ) instead you can find : joe.TakeCash() The word TakeCash() appears six times on this page: in the class diagram box in the upper right-hand corner, in the body text under step 3, above the arrow in the diagram under step 3, twice in the lower right-hand annotation, and once in the annotation directly under step 3. These were all changed to ReceiveCash(). (124) In the first line of body text, change boldfaced text Òvalue typesÓ to ÒtypesÓ. In the first boldfaced heading, change ÒValue typesÓ to ÒTypesÓ. {124} In the second bulleted list, second bullet, change this: Ò-127 to 128Ó To this: Ò-128 to 127Ó {124} In the second bulleted list, second bullet, change this: Ò-32767 to 32768Ó To this: Ò-32768 to 32767Ó {125} In the third boldfaced heading, change Òbuilt-in value typesÓ to Òbuilt-in typesÓ In the Brain Power at the bottom of the page, change -32,767 to -32,768 (126) * Change this: Òscientific application where the numbers need to be extremely accurate, the decimal type has the most precision.Ó To this: Òfinancial application where youÕll be storing currency values, youÕll want to use the decimal type.Ó * In the bottom paragraph, change ÒThereÕs no set size for a string variableÓ to ÒThereÕs no set size for a string objectÓ * Remove this annotation: string is pretty unique. ItÕs the only data type without a set size, except for objects (think about that for a bit). (129) * In the thought bubble, change Òcasting this whole time?Ó to Òconverting types all along?Ó * In the heading underneath it, change Òcasts for youÓ to Òconverts for youÓ * In the second line of body text underneath that, change Òa lot of castingÓ to Òa lot of convertingÓ * In the third-to-last line in that paragraph, change Òautomatically castsÓ to Òautomatically convertsÓ * In the second-to-last line on the page, change Òcasts myIntÓ to Òconverts myIntÓ (130) In the bottom paragraph, change this: Ò(an argument is another name for a methodÕs parameter)Ó To this: Ò(an argument is what C# calls the value that youÕre passing into a methodÕs parameter)Ó {130} Change Òand converted the result to a double.Ó to Òand the = operator converted the result to a double.Ó (131) Add this to the end of the first paragraph: Ò(Sometimes C# can do the conversion automatically Ð like if your method expects an int, but you pass it a short Ð but it canÕt do that for ints and strings.)Ó (132) * In the instructions, change Òknow them allÓ to Òknow a lot of themÓ [p161, too] * Add an annotation to the top of the page: ÒActually, C# does give you a way to use reserved keywords as variable names, by putting @ in front of the keyword. You can do that with non-reserved names too, if you want to.Ó (139) Diagram's arrow text, bottom right; "Every one of these labels is reference variable, but ...åÓ Change the annotation just underneath and to the right of the picture to this: ÒEvery one of the labels is a different reference variable, but they all point to the SAME Guy object.Ó [140]Cooemt beginning "The first line had ...", just above paragraph 2; This is from the 4/08 printing. In 1 Here's some code that creates an object. Guy joe = new Guy(); {Name = "Joe". Cash = 50}; The explanation says, "The first line had a declaration that created the label. The second line created the object and slapped a label on it." Actually, the first line declares a Guy reference variable (joe) as well as creating a new Guy object. The second line merely populates two fields and is superfluous. Moreover, the Name could be anything (I made it Jack in my test) but the object would still be referenced as joe (joe.Name = "Jack"). This might seem trivial, but to an old VB programmer transitioning to C#, objects and references can be confusing. Precision in the explanation helps. Change the top annotation to this: When you use the ÒnewÓ statement, youÕre telling C# to create an object. When you take a reference variable like ÒJoeÓ and assign it to that object, itÕs like youÕre slapping a new label on it. (146) Add this annotation: strings and arrays are different from all of the other data types youÕve seen because theyÕre the only ones without a set size (think about that for a bit). (149) An array's length box; last line change "nubmered" to "numbered" {151} Step 3 "Build your form" first sentence; It reads "label1 through lablel6" and it should be "label1 through label6" [153]There are No Dumb Questions; The Line: Look inside the InitializeComponent() method - You'll find "new Form1(); Should read as: Look inside the Main() method - You'll find "new Form1(); Changed ÒInitializeComponent()Ó to ÒMain()Ó. (153)Dumb Questions, middle column, last line of answer; Currently: "... reference ot it somewhere." Should be: "... reference to it somewhere." {154} * In the first bullet, change 256 to 255. * Swap the second and first bullets, so the word ÒALWAYSÓ is at the top. Add this annotation above the Bullet Points box pointing to the word ÒALWAYSÓ: ÒThereÕs actually a very specific case where you donÕt declare a type Ð youÕll learn about it when you use the ÔvarÕ keyword in chapter 14.Ó * Change bullet 5 from this: ÒThe compiler wonÕt let you set a variable equal to a value of a different type unless you cast it.Ó To this: ÒThere are a few types (like short to int) that C# knows how to convert automatically. Other than those, the compiler wonÕt let you set a variable equal to a value of a different type unless you cast it.Ó (154) In the last answer, sixth line, change Òwith an classÓ to Òwith a classÓ (167) code at the top of the page add an annotation pointing to "public Label MyLabel; // My Label" that reads: "Once you set MyLabel to one of the labels on the form, you'll be able to change the label's text using MyLabel.Text. And the same goes for MyRadioButton!" {169} Top, Center; The suggested code for MyBet cannot be used because it requires knowledge of constructors, which isn't discussed in the book until p. 197. Per Andrew, the code should read as follows: MyBet = new Bet() { Amount = 7, Dog = 3, Bettor = this }; Change the code on the top right arrow from: MyBet = new Bet(7, 3, 8) To: MyBet = new Bet() { Amount = 7, Dog = 3, Bettor = this }; {190} first item circled; The instructions ask the reader to circle items that won't compile. The following line has "const" circled yet it will compile:private const int loyalCustomerOrderAmount = 60; Remove the top annotation, arrow and circle around the word ÒconstÓ. {193} In the body text, change this: Òevery time a field is calledÓ To this: Òevery time a property is usedÓ And in the third and fourth annotations, change ÒNumberOfCows fieldÓ to ÒNumberOfCows propertyÓ (193) In the second annotation, change ÒYou use propertiesÓ to ÒYouÕll often use propertiesÓ (194) - top left annotation Change the first few words from this: Name this button Calculate to this: Name this button "calculate" {195} last line of body text on the bottom of the page Add this right before the last sentence that starts "Now your Farmer class...": You can't modify BagsOfFeed from outside the Farmer class -- you'll need to remove that line in order to get your code to compile, so remove the button from the form. {196} * body text at the top of the page Change the last sentence from this: So letÕs change it to a read-only automatic property. To this: So letÕs change it to a read-only property that uses a backing field. * New screenshot * In step 1, change this: Use prop-tab-tab to add a read-only automatic property: public int FeedMultiplier { get; private set; } to this: (make sure the code is still in courier): Use prop-tab-tab to add a read-only property. But instead of adding an automatic property, use a backing field: private int feedMultiplier; public int FeedMultiplier { get { return feedMultiplier; } } * Change the annotation to this: This property acts just like an int field, except instead of storing a value it just returns the backing field, feedMultiplier. And since there's no set accessor, it's read-only. It has a public get, which means any other class can read the value of FeedMultiplier. But since its set is private, that makes it read-onlyÑit can only be set by an instance of Farmer. * Add another annotation pointing to the "private int feedMultiplier" line: Since we changed FeedMultiplier from a public const to a private int field, we changed its name so it starts with a lowercase ÒfÓ. ThatÕs a pretty standard naming convention youÕll see throughout the book. * In the third line of code under step 2, change "FeedMultiplier" to "feedMultiplier" (lowercase f). (196) 1st paragraph, line 3; In line 3 of the body text, change ÒYouÕve seen how you poorÓ to ÒYouÕve seen how poorÓ {197} * Remove the first line of code ("private int feedMultiplier;") and the two annotations that point to it ("We'll change feedMultiplier..." and "Since we changed FeedMultiplier..."). * New screenshot * In the space that opened up by removing the line of code and two annotations, add one annotation with an arrow pointing down (hopefully the extra space will make the page look less cluttered): The 'this' keyword in this.feedMultiplier tells C# that you're talking about the field, not the parameter with the same name. * body text for step 1 Change this: WeÕll change feedMultiplier from a const to an int. WeÕll need a value for it, so letÕs make sure it gets passed into the constructor. to this: Since we changed feedMultiplier from a const to an int, now we need an initial value for it. So let's make sure it gets passed into the constructor. (make sure you retain the Courier font for the keywords and variable names) * body text for step 2 Add this sentence to the end: Once you replace the new statement, both errors will go away and your code will work! {198} * code in "Constructors Way Up Close" box Remove the first line of code ("private int feedMultiplier;"). It's not needed here, and this will let you move the rest of the code and the middle annotation up to create more space in the box. That will reduce the clutter. You can make the arrow under the top-left annotation shorter, and you can get rid of the arrow under the top-right annotation entirely and just have the bracket point to the annotation directly. * Watch It! box Change "numberOfCows" to "feedMultiplier" and "NumberOfCows" to "FeedMultiplier". (Make sure you retain the Courier formatting.) And change the hyphen in the sixth line to a colon. So the text should look like this: Did you notice how the constructorÕs feedMultiplier parameter looks just like the backing field behind the FeedMultiplier property? If you wanted to use to the backing field in of the constructor, youÕd use Òthis.Ó: feedMultiplier refers to the parameter, and this.feedMultiplier is how youÕd access the private field. {199} * In the third answer, fifth line, change Òwhen a field gets accessedÓ to Òwhen a property gets accessedÓ * In the third answer, last line, change Ògetting or setting the fieldÓ to Ògetting or setting the propertyÓ * In the fourth answer, second paragraph, fourth line, change Òtype of the fieldÓ to Òtype of the propertyÓ * In the sixth answer, second line, change Òread-only fieldÓ to Òread-only propertyÓ * In the sixth answer, fourth line, change ÒReadOnly fieldÓ to Òread-only propertyÓ * In the sixth answer, second paragraph, second line, change Òyour field can onlyÓ to Òyour backing field can onlyÓ * In the sixth answer, second paragraph, fourth line, change ÒPassword fieldÓ to ÒPassword propertyÓ (201) second paragraph of first Answer at top Add the following text to the beginning of the paragraph: "Case matters in C#. You can have two different variables called Party and party in the same method. It'll be confusing to read, but your code will compile just fine." (230) Pool puzzle solution Rowboat class; This block of code is missing a colon; public class Rowboat boat { public string rowTheBoat() { return "stroke natasha" } } should be: public class Rowboat : boat { public string rowTheBoat() { return "stroke natasha" } } (230) In the pool puzzle solution, in the first blank, change ÒBoatÓ to Ò: BoatÓ (233) Change the first sentence of the body text from this: If your class has a constructor, then any class that inherits from it must call that constructor. To this: If your class has constructors which take parameters, then any class that inherits from it must call one of those constructors. In the middle right-hand annotation, change ÒdidnÕt inherit the constructor properlyÓ to ÒdidnÕt call the base constructorÓ (235) In step 2, second bullet, change Òsubclasses only inheritÓ to Òsubclasses can only seeÓ Add an annotation pointing to that bullet that says: ÒLater on, youÕll learn about the ÔprotectedÕ keyword. A protected field is public to a subclass, but private to everyone else.Ó {236} Code, comment for CalculateCost(); The comment still refers to the cost of beverages for the base CalculateCost() method. This comment probably belongs with the Dinnerparty override method. Remove this line of code from the bottom block of code on the page: // Each person costs $25 for food plus cost of beverages (239) number 2; On page number 239, Number 2, second sentence, it says "Once the queen's done assinging". Should be assigning. (240) Text in grey block on the bottom of the page; In the box where the head says "String.IsNullOrEmpty", the sentence goes a bit weird. "Since each bee stores its current job as a string, the way the worker knows whether or not he's not currently doing a job is to check if his CurrentJob property-". If his CurrentJob what? Change the first sentence in the ÒString.IsNullOrEmpty()Ó box at the bottom of the page to: Each bee stores its current job as a string. So a worker can figure out if heÕs currently doing a job by checking his CurrentJob property Ð itÕll be equal to an empty string if heÕs waiting for his next job. (245) * "Add Existing Item" helper box; The box titled "Add Existing Item" leaves out the step to choose "Add Existing Item" from the menu. It says: - Right click on the project name in the new project's Solution Explorer in the IDE - Navigate to the old project's folder It is between these two steps that the "Choose 'Add Existing Item' from the menu" would be useful here. I was trying to follow the directions, not realizing that one of the key steps is the title of the box. * In the third line in the box on the bottom of the page, change this: right-click on the project name in the new projectÕs Solution Explorer in the IDE, navigate to ... to this: right-click on the project name in the new projectÕs Solution Explorer in the IDE, select ÔAdd Existing ItemÕ from the menu, navigate to ... (255) Change this: ÒSo if you want your interface to require a field with a certain name and type, just use a property instead Ð itÕll accomplish the same thing.Ó To this: ÒSo if youÕve got a problem that looks like it might be solved by adding a field to an interface, try using a property instead Ð the odds are that itÕll do what youÕre looking for.Ó [265] middle; thisCollector = workers[i] as INectarCollecter; this should be thisCollector = Bees[i] as INectarCollecter; (273) In the second bullet, change the second sentence to: You canÕt mark a class privateÑunless that class lives inside another class, in which case itÕs only available to instances of its container class. Then itÕs private by default, and if you want it to be public you need to mark it public.. (273) Add the following sentence to the end of the fourth bullet: ÒYou can combine this with protected Ð anything you mark protected internal can only be accessed from within the assembly or from a subclass. Add an annotation underneath the bottom bullet: ÒSealed is a modifier, but itÕs not an access modifier. ThatÕs because it only affects inheritance Ð it doesnÕt change the way class can be accessed.Ó {275} Add a closing bracket to the bottom of the code under step 3. It should line up with the ÒpÓ in ÒpublicÓ in the first line of code. (284)Last paragraph by Interface; Interface says "And that's just plan rude" - plan should be plain. (298) step #3, second bullet point; (that'll be passed in by form) should be (that'll be passed in by the form) (301) 13 lines from the bottom of the page - Remove "0," from a line of code Change this: int rand = random.Next(0, myLocation.Exits.Length); to this: int rand = random.Next(myLocation.Exits.Length); (313) In the first answer, change ÒWhat you saw was a constructorÓ to ÒWhat you saw was a methodÓ {315} middle of page; Console.WriteLine(cards[i].ToString()); should be Console.WriteLine(cards[i].Name()); {317} In step 1, change this: List cards = new List(); To this: List cards = new List(); {319} Sharpen Your Pencil Swap "object o = myList[1];" and "int theSize = myList.Count;" so they're in the same order as on page 320. [321] First block of code for adding new list; The list for addding new shoes is missing the "Shoe" object/class field right before ...Style.Sneakers it should read { Style = Shoe.Style.Sneakers, ...} Add an annotation in the white space in the box at in the lower right-hand corner of the page (you may need to widen the box a little to accommodate it): Remember, the Style enum isnÕt inside the Shoe class, so itÕs just ÒStyle.SneakersÓ, not ÒShoe.Style.SneakersÓ. {322} In bullet #5, change Òtype parameterÓ to Òtype argumentÓ Change this code: List name = new List(); To this: List name = new List(); (348) 1st line of comments in 2nd AskForACard() method; // Ask the other players for a value. first should be: // Ask the other players for a value. First {349}1st block of code; Full details: http://www.headfirstlabs.com/phpBB2/viewtopic.php?t=6458 Add an annotation pointing to the code under step 6: We used a partial class to add this static method to Card to make it easy for you to see whatÕs going on. But you donÕt need to use a partial class -- if you want, you can just add it straight into the existing Card class. {369}Bottom diagram (How the inventory scroll works); The label on the top arrow from "Inventory Icon Clicked" Form object image to Game object image is missing a right parenthesis on the "if" statement. Is: if (game.CheckPlayerInventory("Bow") { Should be if (game.CheckPlayerInventory("Bow")) { ================================================== The label on the bottom arrow between the same two object images uses curly braces on the method call, not parentheses. Is: game.Equip{"Bow"}; Should be game.Equip("Bow"); (383) bullet #4; Check use the Game .... should be Check the Game... 5th Point Text; Text is identical to 1st point text on previous page, and should clearly not be. In step 4, change the first few words to: check the Game objectÕs In step 5, change the body text to this: The rest of the method does three things. First it checks to see if the playerÕs already picked up the weapon in the room, so it knows whether or not to display it. Then it checks to see if the player died. And finally, it checks to see if the playerÕs defeated all of the enemies. If he has, then the player advances to the next level. (387) In step 1, change Òtext or binary dataÓ to Òyour dataÓ (398) middle annotation; propery should be property (399) The second comment on the left hand side of the page says "..and opens the folder specified in the InitialFolder property". But there is no InitialFolder in the code, there's an InitialDirectory. In the bottom left-hand annotation, change InitialFolder to InitialDirectory. (413) Change the leftmost annotation from this: Every case must end with Òbreak;Ó. To this: Every case ends with Òbreak;Ó so C# knows where one case ends and the next begins. (You can also end a case with ÒreturnÓ Ð the program will compile as long as thereÕs no way for one case to Òfall throughÓ to the next one.) (417) bullet #3; "you can go back to fhe file....." should be "you can go back to the file...." (418) brain barbell; Listobject should be Listobject In the curved text under the bottom circle in the box, change ÒList objectÓ to ÒList objectÓ. {423} bullet #4; in button2_click event handler, DealCards(....) should be outside of the using block. In last four lines of code under step #4 need, the ÒDealCards...Ó line needs to be moved below the second-to-last bracket and unindented by two spaces: Deck deckFromFile = (Deck)bf.Deserialize(input); } DealCards(deckFromFile, ÒWhat I read from the fileÓ); } (433) Add an annotation pointing to ÒReadBlock()Ó in the top paragraph: The reason the methodÕs called ÒReadBlock()Ó is that when you call it, it ÒblocksÓ (which means it keeps executing and doesnÕt return to your program) until itÕs either read all the characters you asked for or run out of data to read. (433) Add an annotation (without an arrow) to the space in the bottom left-hand corner: The hex dumper works just fine for text files. But thereÕs a problem. Use File.WriteAllBytes() to write an array of bytes with values over 127 to a file and then run it through your dumper. Uh-oh Ð theyÕre all read in as ÒfdÓ! ThatÕs because StreamReader is built to read text files, which only contain bytes with values under 128. HereÕs a bonus exercise: See if you can figure out how to use the BinaryReader class to fix the problem! (434) In the sidebar in the lower-right corner, change the text Òusing two bytes each.Ó to Òusing two or more bytes each.Ó Add an annotation at the bottom of the page pointing to the sidebar: ÒThis encoding is called UTF-8, which .NET uses by default. You can tell File.WriteAllText() to use a different encoding by passing it a different Encoding object. You can learn more about Unicode encodings at http://unicode.org.Ó (448) In the title bar of the third class box on the bottom, change ÒOverFlowExceptionÓ to ÒOverflowExceptionÓ (448) Second paragraph; The text states: "The Exception class has a couple of useful members. The Message properties stores an easy-to-read message..." It should be: "... The Message property ..." as there's only one of them. In the first line of the second paragraph, change ÒMessage propertiesÓ to ÒMessage propertyÓ. (462) Second Answer, first sentence.; "Whenever you program throws an exception, the runtime environment will search through your code looking for a catch block to that matches it." Either that "to " should not be there or it should say "... to match it". In the second answer (the top two lines of the second column), change: for a catch block to that matches it to: for a catch block that matches it {468} Code example, try block in consumeHoney_Click method; The button click handler creates a HoneyDeliverySystem object called delivery and then tries to call a FeedHoneyToEggs method without specifying the parent object's name: FeedHoneyToEggs()" In the bottom block of code, eight lines from the bottom, change: FeedHoneyToEggs(); To: delivery.FeedHoneyToEggs(); (472) Fifth annotation; Surely the underline is misplaced and should be under "must", not over it? Third paragraph, second sentence; The text states: "First, let's use a built-in object that implements IDisposable, Stream." Change to: "First, let's use built-in object Stream, which implements IDisposable." (485) Annotation to Umpire object; The note states: "The umpire checks every ball ... and monitor what happens." This should be "... umpires check ..." or "... monitors ...". In the last line of the annotation pointing to the Umpire object, change ÒmonitorÓ to ÒmonitorsÓ (485) Final paragraph, 2nd and 3rd sentences; There is inconsistent use of singular/plural in the last paragraph: "... So you write code to raise an event, and then you write code to handle those events ... Then, whenever an event is raised, your handlers kick into action." To be consistent, this should be: "... you write code to raise an event, and ... write code to handle that event" and "... your handler kicks into action." In the last paragraph on the page, change Òyour handlers kickÓ to Òyour handler kicksÓ {496} Exercise Solution, declaration of BallEventArgs class; The definition of the BallEventArgs class is missing its inheritance from the EventArgs base class. It should look like this: "public class BallEventArgs : EventArgs { ... " This was correct in the original, type this in, version on p492, so it's only a minor mistake, almost a typo. Change the boldfaced line of code in the middle of the page from this: public class BallEventArgs { to this: public class BallEventArgs : EventArgs { (498) bullet #2; messagebox.show should say "You just clicked on the form" first annotation; "You can see all of the events for a control by click on it..." should be "...clicking on it...." {498} Step 1; The text for Step 1 states: "Create a new Windows Application project. Bring up the form, and go to the Properties window." Now, it is not clear what "bring up the form" means. When you create a new project, the IDE displays the Form1.cs [Design] tab but the Properties window shows the solution (e.g. "Chapter 11 Program 2") Project Properties. It is not clear that you have to click on the Form1.cs [Design] **tab** to switch to the desired Form1 ... properties. Change ÒBring up the form, and go to the Properties window.Ó to ÒGo to the Properties window for the form.Ó (498) First annotation; The text for note 1 states: "You can see all of the [pre-made] events for a control by click on it and then click on this events button in the properities window." "pre-made" has already been deleted in an earlier update. The English is a bit strained, but the simplest way to fix it is to change the "click"s to "clicking"s. It would also be sensible to correct the spelling and Capitalization of "properities window" to "Properties window" while you're at it. In the top right annotation, change ÒYou can see all of the events for a control by click on itÓ To ÒYou can see all of the events for a control: just click on itÓ (499) Add an annotation pointing to the code under step 6: "When you click these buttons, they chain different event handlers onto the form's Click event." Then add an annotation under it, pointing up at it: "That means you won't see anything when you click the buttons! You'll need to click on the form, because the buttons change the form's behavior by modifying its Click event." (506) Pool Puzzle Solution, 3rd line of code; in the line: "this.Load += new EventHandler(Minivan);" "Load" is already highlighted in the solution but "Minivan" is not. As "Minivan" is one of the items that had to be added from the Pool, it should also be highlighted. By the way, "Van", "Car", and "Tricycle" are possible alternative names for the "Minivan" event handler. There's nothing to prevent them being used in the Pool Puzzle, provided whichever name is chosen is used in both the Form1() constructor and for the 4th event handler. Perhaps "Tricycle" should be replaced by "Bicycle", and "Van" or "Car" replaced by "Towtruck". The third of these could be removed from the Pool as it isn't really necessary, except as a source of confusion. In the pool puzzle on page 504, change the third line of code from this: this.______ += new EventHandler(____________); to this: this.______ += new EventHandler(Minivan); (510) there are no Dumb Questions, Annotation 2; The last note states: "The first one you'll learn about is called the "Publisher-Subscriber" pattern." I started reading HFDP before HFC#... and actually, it's called the "Observer" pattern! In the bottom right-hand annotation, change this: the ÒPublisher-SubscriberÓ pattern, To this: the ÒObserverÓ (or ÒPublisher-SubscriberÓ) pattern, (510) there are no Dumb Questions, Answer 3; The fifth sentence states: "So if you mark an event private, then other instances if the same class can subscribe to it." That "... if the same class" should be "... of the same class". (521) Annotation to Step 4; The note states: "*Hint: We used NectarGatheredPerTurn, nectar, and NectarHarvested in this method, but nothing else." The variable for the flower's nectar is called "Nectar" (on p520). I'm wondering whether the list style "first, second, and third" has been used previously in this book. I would have thought it should be "first, second and third" - i.e. no final comma - but maybe that's just me! In second line of the annotation under step 4, capitalize ÒNectarÓ {529} Hive class diagram; getLocation should be GetLocation In the bottom line in the class diagram box in the upper right-hand corner of the page, change ÒgetLocationÓ to ÒGetLocationÓ (529) Step 3, second sentence; In Step 1, the skeleton code for the Hive class states "... locations should be private, ...". Step 3 says the GetLocation() method should "look up that string in the Locations dictionary, ...". I think "Locations" should be treated as a variable name - in other words with correct (lower) case and in fixed-width font. In the second line of step 3, change ÒLocationsÓ to ÒlocationsÓ and put it in the Courier code font [536] World constructor; There should be a line to instantiate the Hive variable but it is missing. Change the body text at the top of the page to this: The World class is actually one of the simpler classes in our simulator. HereÕs a starting point for the code. But if you look closely, youÕll notice that itÕs missing a few things (which youÕll add in just a minute). {537} second answer on bottom of page; "..beginning of a list of five bees..." should be "..beginning of a list of five flowers..." In the third line of the second answer, change ÒbeesÓ to ÒflowersÓ (539) final answer; "No reason reinvent the wheel..." should be "No reason to reinvent the wheel..." (539) There are no Dumb Questions, Answer 3; Sentence 2 starts: "However, just becase .NET uses them that way, ..." That should be "... because ...". In the third line of the last answer, change ÒbecaseÓ to ÒbecauseÓ (548) top right; In the second-to-last line of the ÒDateTime & TimeSpanÓ box, change ÒobectÓ to ÒobjectÓ (556) middle; In the second line of body text, change Langauge to Language (560) move the arrow from the second-to-last annotation a little to the right Ð itÕs overlapping the code. {561} middle; When reading in the file the variable name should be input as opposed to output. In lines 15 to 17 of the code, the word ÒoutputÓ appears three times Ð change it to ÒinputÓ. using (Stream input = File.OpenRead(openDialog.FileName)) { world = (World)bf.Deserialize(input); framesRun = (int)bf.Deserialize(input); Then change the annotation pointing to the bottom to lines to: HereÕs where we deserialize the world and the number of frames run from the file {572}Sharpen Your Pencil, explanation for fourth code item; The Solution states:- "This loop searches through all the controls on the form until it finds a label with the text "Bobby". Once it finds the label, it removes it from the form." This is not correct. What the loop does is this:- The loop searches through all the controls on the form. If it finds a label with the text "Bobby", it remembers it (but it doesn't stop looking). After the loop exits, if a label was found (controlToRemove is no longer null), it is removed from the form. If not, a null reference exception is thrown. If there was a break to get out of the loop once a control was found, or the loop was executed backwards in the manner of the bees, then it would be possible to remove one or more controls. As written, it is only possible to remove the last one. Add an annotation in the space above the fourth answer pointing down at it: What happens thereÕs no control named ÒBobbyÓ in the Controls collection? (577) whole page; Bullet point 3 is repeated Replace the three lines of the body text under step 3 with this (ÒanimationTimer.Dispose()Ó should be in Courier code font): Change the new Dispose() method that the IDE added for you so that it calls animationTimer.Dispose(). {582}MouseClick Event Handler code; The code given shows the MouseClick EventHandler as being in the main form - Form1_MouseClick(). Should it be in the FieldForm - FieldForm_MouseClick() (and the HiveForm)? Maybe there should be an annotation saying to make sure the event handler is added to the actual form, not a PictureBox or the co-ordinates will be PictureBox-control-relative. In the first line of code in the middle of the page, change ÒForm1_MouseClickÓ to ÒFieldForm_MouseClickÓ (583) top annotation; "...other class needs to update to any..." should be "...other class needs to update any..." In the fourth line of the upper right-hand annotation, change Òto any of its propertiesÓ to Òany of its propertiesÓ. {585} MoveBeeFromHiveToField method; why does this need a Bee parameter? Remove Ò, Bee beeÓ from the declaration of the MoveBeeFromHiveToField method, so it looks like this: private void MoveBeeFromHiveToField(BeeControl beeControl) { {589} Step 1; the constants to increase bees is in the Hive class, not the World class bullet #3; "of of" bullet #3; "bee image are sometimes" should be "bee images are sometimes" In the second line under step 1, change ÒWorld classÓ to ÒHive classÓ In the fourth line under step 3, change Òareas of of the beeÓ to Òareas of the beeÓ In the last line under step 4, change Òthe bee image are sometimesÓ to Òthe bee images are sometimesÓ {602}Step 2 code example; Step 1 says to double-click on Paint in the Form's Events list. This produces an Event Handler called Form1_Paint. Step 2 shows this code but now it's called UserControl1_Paint. Surely it should (still) be Form1_Paint? In the first line of code under step 2, change ÒUserControl1_PaintÓ to ÒForm1_PaintÓ. {602}Step 3 first sentence; Step 3 says:- "Add the new DrawBees() method from the previous page into your new user control." Firstly, the method from the previous page is called DrawBee () not DrawBees. Secondly, the last project that included a user control - BeeControl -was different to the one with the picture. The BeeControl was used to draw animated bees on the Hive and Field forms, if I am remembering correctly. For the exercises on p601 and 2, I created a WindowsApplication project and copied the files and resources from the project that drew the Bee, Flower, and "Nectar here" string. That project did not include a user control, or at least, mine didn't! In the first line under step 3, change ÒDrawBees()Ó to ÒDrawBee()Ó, and put it in Courier code font. (629) Change the fifth paragraph from this: Finally, .NET sends the garbage collector out again. This time, your object is dead, and the collector tosses it away. Here, finally, your destructor runs... possibly several minutes after the last reference to the object was removed or changed. To this: Finally, .NET sends the garbage collector out again. Your destructor runs... possibly several minutes after the last reference to the object was removed or changed. Now that itÕs been finalized, your object is dead, and the collector tosses it away. (635) In the first question, fourth line, change this: Òmay have already been collected.Ó To this: Òmay have already been finalized.Ó (637) Add an annotation pointing to the second paragraph of body text in the middle of the page: ÒAll structs inherit from System.ValueType, which in turn inherits from System.Object. ThatÕs why every struct has a ToString() method Ð it gets it from Object. But thatÕs all the inheriting that structs are allowed to do.Ó (637) In the sidebar, change this: ÒStructs are best used for storing data, but are not as useful as objects when it comes to representing actual behavior.Ó To this ÒStructs are best used for storing data, but the lack of inheritance and the way theyÕre managed in memory can be a serious limitation.Ó Add an annotation pointing to this sentence: ÒThatÕs why you donÕt usually find yourself defining your own structs. But that doesnÕt mean they donÕt have their uses!Ó (638) In the second line of body text, change ÒstringÓ to ÒdecimalÓ. Change the second line of code under the first bullet from this: string name = ÒFingersÓ; to this: bool Scary = true; And in annotation pointing to that line of code, change this: Òint and boolÓ To this: Òint and boolÓ (639) Next to step 1, add this annotation (no arrow): Remember back in the beginning of the book when we said that methods and statements ALWAYS live in classes? Well, it turns out that's not quite exactly 100% accurate -- they can also live in structs. (642) Add an annotation on page 642 pointing to step #2: ÒThereÕs a special case where value types donÕt get boxed: if they live inside an object. If youÕve got a class with an int field, that int doesnÕt need to be boxed before itÕs added to the heap, because itÕs already got a container Ð the object that itÕs a part of.Ó {643}Halfway through code on left; Line 5 of the code on the left should be wine.Set(book); Alternatively, the Set method in the Table struct could be called SetA. Similarly, line 6 of the code on the left should be book.Set(wine); Or, the Set method in the Hinge class should be called SetB. In lines 5 and 6 of the code on the left-hand side of the page, change ÒSetAÓ and ÒSetBÓ to ÒSetÓ: wine.Set(book); book.Set(wine); {648}top paragraph, step 1 code, step 3 code; The name of the class is inconsistent throughout the example. The end of the first paragraph tells the reader to add a file called MyExtensions.cs The name of the class in step 1 is HumanExtensions The name of the class in step 3 is StringExtensions In the last line of bodytext, change ÒMyExtensions.csÓ to ÒHumanExtensions.csÓ, and put it in Courier code font. In the first line of code under step 3, change ÒStringExtensionMethodsÓ to ÒHumanExtensions {649} change this magnet: public static void Main { To this: public static void Main() { Add semicolons to the ends of these two magnets: string s = i.ToPrice() s.SendIt() Change these two magnets that say Òb.Green();Ó To this: b.Green().SendIt(); {650}Column of magnets on the right; The code for the Extension Magnets won't run as written. The Main method is missing parentheses. It should be Main() The 5th and 6th lines are missing semicolons. (The are also missing semicolons on the magnets on page 649) They should be: string s = i.ToPrice(); s.SendIt(); In order to get the correct output, both the 8th and 10th lines are missing part of the code. They should both be: b.Green().ToPrice(); Also, there should be two more magnets on page 649 that say, ".SendIt();" There are five magnets that need to be changed on pages 649 and 650 (all five magnets appear on both pages). {650} change this magnet: public static void Main { To this: public static void Main() { Add semicolons to the ends of these two magnets: string s = i.ToPrice() s.SendIt() Change these two magnets that say Òb.Green();Ó To this: b.Green().SendIt(); {669} Page 669 uses this code to initialize the lines array:- Line [] lines = { new Line ( { "eating", "carrots,", "but", "enjoy", "Horses" } , 1), etc. while the Pool Puzzle Solution on p670 has:- Line [] lines = { new Line ( new { "eating", "carrots,", "but", "enjoy", "Horses" } , 1), ... The correct code should read:- Line [] lines = { new Line ( new string [] { "eating", "carrots,", "but", "enjoy", "Horses" } , 1) new Line ( new string [] { "zebras", "Cows", "hay", "bridge", "bolted" } , 2), new Line ( new string [] { "fork", "dogs!", "engine", "and" } , 3), new Line ( new string [] { "love", "they", "apples.", "eating" } , 2 ), new Line ( new string [] { "whistled.", "Bump" } , 1 ) }; In the left-hand block of code, there are five lines that start with: new Line( { Ò... Change them so they start with: new Line( new string[] { Ò... {670} Pool Puzzle, initialization of lines array; In the left-hand block of code, there are five lines that start with: new Line( { Ò... Change them so they start with: new Line( new string[] { Ò... (670) Pool Puzzle Solution, first annotation; Whoops, sorry, sent that before I'd overtyped the new description! The annotation states: This first LINQ query divides the Line objects in the line[] array into two groups, grouped by their Value, ... Surely there are three groups, with Value = 1, 2 and 3? We actually want only the first two, but that hasn't happened yet. In the second line of the top annotation, change Òinto two groupsÓ to Òinto groupsÓ (671) Annotation to Step 3, second sentence; The annotation, second sentence states: "When you use an object initializer, you create an anonymous by typing a series of names and values inside curly brackets." It should say something like "... you create an anonymous object..." or "an anonymous type object", though the latter is not so good. In third line of the bottom left-hand annotation, change Òyou create an anonymousÓ to Òyou create an anonymous objectÓ {672} Sample code for Step 1; The definition for method FindPurchases starts:- public sList FindPurchases() ... My IDE doesn't seem to know what an sList is, and neither do I, so I'm guessing it should read:- public List FindPurchases() ... In the first line of code, change Òpublic sListÓ to Òpublic ListÓ (677) there are no Dumb Questions, Answer 4; The answer starts:- "Yes, you do have to create them. LINQ object that implements the IEnumerable interface." This doesn't make sense. The first sentence could say just:- "Yes, you do." "have to add them" would match the terminology of the question. That second sentence could state:- "LINQ can only be used with objects that implement the IEnumerable interface." or, slightly shorter but perhaps not so clear:- "LINQ objects must implement the IEnumerable interface." though that runs better into the following explanation. Also, para 2 sentence 2 says:- "When you add it to your project, it automatically does everything..." The first "it" should the "them" to match the LINQ to SQL classes (plural), while the second "it" refers to the IDE, so it would be clearer if it said "the IDE"! The following "it"s would then refer to the IDE again. Change the first two sentences of the fourth answer to: A: Yes, you do. LINQ needs an object that implements the IEnumerable interface. In the second paragraph of the fourth answer, change ÒitÓ to ÒtheyÓ and match the number throughout: ThatÕs why the IDE provides the LINQ to SQL classes for you. When you add them to your project, they automatically do everything you need in order to connect LINQ to a SQL database: they let you drag database objects into its Object Relational Designer, and when you do they automatically read your databaseÕs tables and create classes (like the People class) that LINQ can use to access them. {679}Step 3, code example, join line; There is an inconsistency in the code. The data context variable for the Contacts database is originally created as "context" but the join line that links it to the Starbuzz data calls it "dataContext". This will not compile. It would be better to use "context" for both of them but dataContext would also be OK, but perhaps a bit too long. In the sixth line of code, change ÒdataContextÓ to ÒcontextÓ (712) In the header and first line of body text change ÒWindows Presentation FrameworkÓ to ÒWindows Presentation FoundationÓ. (718) Index "argument"