Exam Ref 70-483: Programming in C#

Errata for Exam Ref 70-483: Programming in C#




The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color Key: Serious Technical Mistake Minor Technical Mistake Language or formatting error Typo Question Note Update



Version Location Description Submitted By Date Submitted Date Corrected
Safari Books Online
?
Objective 2.2 - explicit conversion

The text says "Where you can go implicitly from a derived type to a base type, you need to cast from a derived to a base type". It should be "... You need to cast from a base to a derived type".

Note from the Author or Editor:
On page 109 change the line: "Where you can go implicitly from a derived type to a base type, you need to cast from a derived to a base type" To: "Where you can go implicitly from a derived type to a base type, you need to cast from a base type to a derived type"

Thierry Pauly  Jul 14, 2013  Aug 09, 2013
Safari Books Online
?
Example 2-84

I don't understand this example. It implements a finalizer, but the finalizer calls Dispose(false) which does nothing if the parameter is false. Why implementing a finalizer if it does nothing ? Why implementing a separate Dispose() method with a parameter instead of simply doing its work in Dispose() ? Maybe this example is trying to show a more general pattern, but as it is presented, I fail to see the point. Minor remark: the class is called 'UnmangedWrapper' when I suppose it's meant to be called 'UnmanagedWrapper'

Note from the Author or Editor:
Change the Implementing IDisposable and a finalizer section to: Implementing IDisposable and a finalizer Creating your own custom type that implements IDisposable and a finalizer correctly is not a trivial task. As an example, suppose you have a wrapper class around a file resource and an unmanaged buffer. You implement IDisposable so users of your class can immediately cleanup if they want. You also implement a finalizer in case they forget to call Dispose. Listing 2-84 shows how to do this. LISTING 2-84 Implementing IDisposable and a finalizer. using System; using System.IO; using System.Runtime.InteropServices; class UnmanagedWrapper : IDisposable { private IntPtr unmanagedBuffer; public FileStream Stream { get; private set; } public UnmanagedWrapper() { CreateBuffer(); this.Stream = File.Open("temp.dat", FileMode.Create); } private void CreateBuffer() { byte[] data = new byte[1024]; new Random().NextBytes(data); unmanagedBuffer = Marshal.AllocHGlobal(data.Length); Marshal.Copy(data, 0, unmanagedBuffer, data.Length); } ~UnmanagedWrapper() { Dispose(false); } public void Close() { Dispose(); } public void Dispose() { Dispose(true); System.GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { Marshal.FreeHGlobal(unmanagedBuffer); if (disposing) { if (Stream != null) { Stream.Close(); } } } } There are a couple of things to notice about this implementation: ē The finalizer only calls Dispose passing false for disposing. ē The extra dispose method with the Boolean argument does the real work. This method checks if itís being called in an explicit dispose or if itís being called from the finalizer: o If the finalizer called Dispose, you only release the unmanaged buffer. The Stream object also implements a finalizer and the garbage collector will take care of calling the finalizer of the FileStream instance. Because the order in which the garbage collector calls the finalizers is unpredictable you canít call any methods on the FileStream. o If Dispose is called explicitly, you also close the underlying FIleStream. Itís important to be defensive in coding this method and always check for any source of possible exceptions It could be that Dispose is called multiple times and that shouldnít cause any errors. ē The regular Dispose method calls GC.SuppressFinalize(this) to make sure that the object is removed from the finalization list that the garbage collector is keeping track of. The instance has already cleaned up after itself; so itís not necessary that the garbage collector calls the finalizer. EXAM TIP Itís important to know the difference between implementing IDisposable and a finalizer. Both cleanup your object but a finalizer is called by the Garbage Collector while the Dispose method can be called from code. MORE INFO Implementing IDisposable and a finalizer For more information on how to implement IDisposable and a finalizer see: http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx.

Thierry Pauly  Jul 14, 2013  Aug 09, 2013
Safari Books Online
?
Who should read this book

The section first says "Developers reading this book should have a basic understanding of writing a simple C# program". The next section just below starts by saying "you should have a least one or more years of experience... using C#." This is completely inconsistent. (And I personally believe the first statement is invalid for this book, whose very first chapter is about multithreading !)

Note from the Author or Editor:
Remove the following paragraph at the end of Who should read this book: Developers reading this book should have a basic understanding of writing a simple C# program. You can create and run applications by using Visual Studio. Add the following to the Assumptions section behind behind the first sentence: To run the examples from this book you should be able to create a console application in Visual Studio.

Thierry Pauly  Jul 14, 2013  Aug 09, 2013
Printed
Page xviii
Errata & book support, after the first paragraph

http://aka.ms/ER70-483/errata returns a 404 - File or directory not found error. Took me a while to find it, but the correct link is: http://oreilly.com/catalog/errata.csp?isbn=9780735676824

Note from the Author or Editor:
The link http://aka.ms/er70-483/errata on page xviii is not working. The best solution would be to fix the link. If that's not possible the correct link should be http://oreilly.com/catalog/errata.csp?isbn=9780735676824

Anonymous  Aug 23, 2013  Oct 11, 2013
Printed
Page 6
Listing 1-4

Method ThreadMethod is not used. Its superfluous definition obscures the purpouse of the code listing.

Note from the Author or Editor:
Remove the following lines from Listing 1-4: public static void ThreadMethod(object o) { for(int I =0: I< (int)o;i++) { Console.WriteLine("ThreadProc: {0}", I); Thread.Sleep(0); } }

Jan Dziedzic  Aug 31, 2013  Oct 11, 2013
PDF
Page 9
1st paragraph

The book says: You can use the Thread.CurrentThread class to ask for information about the thread that's executing. Thread.CurrentThread is not a class, it's a property on the Thread class.

Note from the Author or Editor:
Change: You can use the Thread.Current-Thread class to ask for information about the thread thatís executing. To: You can use the Thread.CurrentThread property to ask for information about the thread thatís executing.

Oleg Kolpashchikov  Nov 17, 2013 
Printed
Page 18
1st paragraph after Listing 1.18

"Because the entry method of an application can't be marked as async, the example uses the Wait method in Main. This class uses both the async and await keywords in the DownloadContent method" I don't find any Wait method in Main, and I don't know which class you are referring to. (The one using the async and await keywords)

Note from the Author or Editor:
Change the first line after Listing 1-18 from: Because the entry method of an application can't be marked as async, the example uses the Wait method in Main. to: Because the entry method of an application can't be marked as async, the example accesses the Result property in the Main method which blocks the code until the async method DownloadContent is finished.

Daniel  Sep 04, 2013  Oct 11, 2013
Printed
Page 33
Listing 1-37

Change the second Console.WriteLine from: Console.WriteLine("Locked A and B") to: Console.WriteLine("Locked B and A") (switch A and B).

Wouter de Kort
Wouter de Kort
O'Reilly Author 
Aug 05, 2013  Aug 09, 2013
Printed
Page 39
Listing 1-44

Add the following line after the closing } of the while statement: throw new OperationCanceledException();

Wouter de Kort
Wouter de Kort
O'Reilly Author 
Aug 05, 2013  Aug 09, 2013
Printed
Page 42
Listing 1-46

Change Listing title to: Using the equality operator

Wouter de Kort
Wouter de Kort
O'Reilly Author 
Aug 05, 2013  Aug 09, 2013
Printed
Page 43
Listing 1-50

Change the Listing title to: Short-circuiting the AND operator

Wouter de Kort
Wouter de Kort
O'Reilly Author 
Aug 05, 2013  Aug 09, 2013
Printed
Page 52
Listing 1-69

Change listing title to: Implementing a for loop with a while statement

Wouter de Kort
Wouter de Kort
O'Reilly Author 
Aug 05, 2013  Aug 09, 2013
Printed
Page 59
Paragraph before Listing 1-79

"Listing 1-79 shows how you would write the example in Listing 1-73 with newer lambda syntax." Should be "Listing 1-79 shows how you would write the example in Listing 1-75 with newer lambda syntax."

Note from the Author or Editor:
Change: "Listing 1-79 shows how you would write the example in Listing 1-73 with newer lambda syntax." to "Listing 1-79 shows how you would write the example in Listing 1-75 with newer lambda syntax."

Ilkka H.  Nov 17, 2013 
PDF
Page 80
Listing 1-98

protected constructor should invoke base constructor protected EntityOperationException(SerializationInfo info, StreamingContext context) : base(info, context) Method GetObjectData is virtual and can/should be overriden with invocation of base method public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info.AddValue("entityId", EntityId, typeof (int)); }

Note from the Author or Editor:
Change the following: protected OrderProcessingException(SerializationInfo info, StreamingContext context) to: protected EntityOperationException(SerializationInfo info, StreamingContext context) : base(info, context) And change: public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("OrderId", OrderId, typeof(int)); } to public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); info.AddValue("entityId", EntityId, typeof (int)); } in Listing 1-98

Sergey S  Oct 22, 2013 
PDF
Page 82
Objective review #3

Contructor names should be "LogonFailedException" - not "LogonFailed"

Note from the Author or Editor:
Objective 1.5, question 3. All occurrences of LogonFailed in answer A-D should be changed to LogonFailedException.

Sergey S  Oct 18, 2013 
PDF
Page 98
Listing 2-11

The constructor has the following line: this.maximumNumberOfCards = maximumNumberOfCards; This should be changed into: _maximumNumberOfCards = maximumNumberOfCards;

Wouter de Kort
Wouter de Kort
O'Reilly Author 
Sep 09, 2013  Oct 11, 2013
Printed
Page 116
Table 2-3

In the book, the description of the public access modifier in Table 2-3 is "None; restricted access". Probably this should instead be "Unrestricted access" as the public access modifier allows all callers to access a type or type member without limitation.

Note from the Author or Editor:
Change the description in Table 2-3 for the public accessmodifer to: None; unrestricted access.

Daniel Dittenhafer  Aug 07, 2013  Oct 11, 2013
Printed
Page 123
Objective summary, 5th bullet

The bullet "The access modifiers are public, internal, protected, protected, internal, and private." should probably be modified to remove the comma between the 2nd instance of "protected" and the 2nd instance of "internal" in order to better convey the "protected internal" access modifier. The new sentence would instead read as: The access modifiers are public, internal, protected, protected internal, and private.

Note from the Author or Editor:
Remove the comma between protected, internal. The new sentence becomes: The access modifiers are public, internal, protected, protected internal, and private.

Daniel D.  Aug 07, 2013  Oct 11, 2013
Printed
Page 132
Listing 2-50

The public properties Height and Width should be marked virtual in order for the overridden properties in Listing 2-51 to compile and function properly. Also, the Rectangle class (or Square) needs a parameterless constructor in order for the Listing 2-52 code to build and execute.

Note from the Author or Editor:
Change the code in Listing 2-50 with: class Rectangle { public Rectangle(int width, int height) { Width = width; Height = height; } public virtual int Height { get; set; } public virtual int Width { get; set; } public int Area { get { return Height*Width; } } } Change the code in Listing 2-51 with: private class Square : Rectangle { public Square(int size) : base(size, size) { } public override int Width { get { return base.Width; } set { base.Width = value; base.Height = value; } } public override int Height { get { return base.Height; } set { base.Height = value; base.Width = value; } } }

Daniel D.  Aug 08, 2013  Oct 11, 2013
Printed
Page 133
1st sentence of section Implementing standard .NET Framework interfaces

The sentence has an extra "can" as in "that can you can use on your own types". The first "can" should be removed.

Note from the Author or Editor:
The sentence has an extra "can" as in "that can you can use on your own types". The first "can" should be removed.

Daniel D.  Aug 08, 2013  Oct 11, 2013
PDF
Page 141
Paragraph below the listing 2-62

"The GetAttribute and GetAttributes methods have several overloads..." Correct method names: Attribute.GetCustomAttribute and Attribute.GetCustomAttributes

Note from the Author or Editor:
Change GetAttribute and GetAttributes to GetCustomAttribute and GetCustomAttributes in the paragraph below Listing 2-62.

Sergey S  Oct 18, 2013 
Printed
Page 141
Listing 2-62

using GetCustomAttribute will result in a System.Reflection.AmbigiousMatchException. You must must GetCustomAttributes and then take an element from the array you get from that function.

Note from the Author or Editor:
Change ConditionalAttribute conditionalAttribute = (ConditionalAttribute)Attribute.GetCustomAttribute( typeof(ConditionalClass), typeof(ConditionalAttribute)); to ConditionalAttribute conditionalAttribute = (ConditionalAttribute)Attribute.GetCustomAttributes( typeof(ConditionalClass), typeof(ConditionalAttribute)).First();

Norbert Nolte  Nov 13, 2013 
Printed
Page 142
Listing 2-66

In the paragraph before Listing 2-66 the second sentence states that the attribute shall only be used on methods and parameters but Listing 2-66 set the allowed targets to method and class.

Note from the Author or Editor:
Change AttributeTargets.Class to AttributeTargets.Parameter in Listing 2.66

Anonymous  Oct 02, 2013 
Printed
Page 153
2nd paragraph

In the first sentence, "The IDiposable interface ..." has a misspelled interface name. The name should be IDisposable, with an "s" before the "p".

Note from the Author or Editor:
IDiposable should be spelled IDisposable

Daniel D.  Aug 08, 2013  Oct 11, 2013
Printed
Page 160
next to last line

should be: new String('x', 10000)

Note from the Author or Editor:
In the paragraph after Listing2-88 change new String("x", 10000) to new String('x',10000) (From double quotes to single quotes)

Anonymous  Nov 24, 2013 
Printed
Page 161
4th paragraph

The 2nd sentence of the paragraph should say TextReader, instead of TextWriter.

Note from the Author or Editor:
Change TextWriter to TextReader in the 4th paragraph.

Daniel D.  Aug 08, 2013  Oct 11, 2013
Other Digital Version
175
Example 1-1

The commented portion of the code with "//Displays", the last line displays "//ThreadProc: 10", this line will NEVER display based on for loop in method "ThreadMethod" which stops the loop at 9, not 10.

Note from the Author or Editor:
Remove the line //ThreadProc: 10 at the end of the listing.

Anonymous  Jul 30, 2013  Aug 09, 2013
Printed
Page 189
Listing 3-11

Change listing title to: Collapse multiple spaces with RegEx

Wouter de Kort
Wouter de Kort
O'Reilly Author 
Aug 05, 2013  Aug 09, 2013
Printed
Page 201
forth paragraph

This means that you can check to determine wheather two items are equal by checking their hash codes. Thatīs wrong. Two distinct items can have the same hash code.

Note from the Author or Editor:
After Listing 3-22 (4th paragraph) remove the line: This means that you can check to determine whether two items are equal by checking their hash codes.

Norbert Nolte  Nov 21, 2013 
Printed
Page 226
2nd paragraph under Managing program database...

The first sentence in the paragraph reads "You can construct the compiler to create a PDB...". The word "construct" should probably be "instruct" as in "You can instruct the compiler to create a PDB..."

Note from the Author or Editor:
On page 226 in the second paragraph under Managing program database... the sentence should read 'You can instruct the compiler...'

Daniel D.  Aug 12, 2013  Oct 11, 2013
PDF
Page 226
Listing 3-43

[DebuggerDisplay(ďName = {FirstName} {LastNameĒ)] missing "}" after "LastName"

Note from the Author or Editor:
Change the first line of Listing 3-43 into: [DebuggerDisplay("Name = {FirstName} {LastName}")]

Sergey S  Oct 18, 2013 
Printed
Page 243
3rd bullet of Performance Counter types

AvergateTimer32 - this should be AverageTimer32.

Note from the Author or Editor:
In the three bullet points on page 243, the last item should read AverageTimer32 instead of AvergateTimer32

Daniel D.  Aug 12, 2013  Oct 11, 2013
Printed
Page 247
Within Objective 3.1: Review

The answer to question 3 of the Objective 3.1 Review is missing. Page 247 ends with the answer to question 2, and page 248 begins with the Objective 3.2 Thought experiment.

Note from the Author or Editor:
The answer for Objective 3.1, question 1 is missing. The answer should be: 1. Correct answer: B A. Incorrect: The regular Parse method will throw an exception if the value the user entered is not a DateTime. This is something you need to expect when you parse user input. Using TryParse avoids the exception. B. Correct: TryParse should be used when working with user input. C. Incorrect: Convert.ToDateTime calls Parse internally. This will throw an exception when the user input is not in the correct format. D. Incorrect: RegEx.Match will search the input string for the first match to the specified regular expression. It won't convert the input string to a DateTime.

Daniel D.  Aug 08, 2013 
Printed
Page 247
user enters an invalid date,,

Comma is repeated twice.

Note from the Author or Editor:
On page 247, Objective 3.1 Review question 1 answer A, the extra comma (,) after 'the user enters an invalid date' should be removed.

Dmytro S. Yefymov  Aug 22, 2013  Oct 11, 2013
PDF
Page 248
Objective 3.2: Review # 3 C

This answer should be "Incorrect"

Note from the Author or Editor:
Objective 3.2 question number 3 should have C marked as Incorrect in the answers section.

Sergey S  Oct 18, 2013 
Printed
Page 249
Objective 3.3: Review - Question 2

The original question includes the directive to "Choose all that apply". Deploying to the GAC requires the assembly to have a strong name. As such, it seems to me the correct answer to this question should include "D. Strongly name the assembly" in addition to "B. Deploy the assembly to the GAC".

Note from the Author or Editor:
Mark answer D for question 2 of objective 3.3 on page 249 as correct. Change the answer to: Correct. Strongly naming an assembly is required to deploy an assembly to the GAC where it can be shared by all applications.

Daniel D.  Aug 11, 2013  Oct 11, 2013
PDF
Page 259
Paragraph below the listing 4-12

"The Path class offers some other helpful methods: GetDirectoryName, GetExtensions,..." Correct name of the last method is singular GetExtension

Note from the Author or Editor:
Change GetExtensions to GetExtension

Sergey S  Oct 19, 2013 
Printed
Page 260 - 263
string path = ...; string myValue = ...

@>>c:\temp\test.dat>> have to be @"c:\temp\test.dat" (pp. 260,261) <<MyValue>> have to be "MyValue" (p. 261) @>>c:\temp\bufferedStream.txt>> have to be @"c:\temp\bufferedStream.txt" (p. 263) ""A line of text.>> have to be "A line of text" (p. 263)

Note from the Author or Editor:
In Listing 4-14, 4-15, 4-18 and 4-19 replace the << character with ": string path = @"c:\temp\test.dat"; On page 261 in Listing 4-15 change <MyValue> to "MyValue" Listing 4-19 change <<A line of tekst.>> to "A line of text."

Dmytro S. Yefymov  Aug 24, 2013  Oct 11, 2013
ePub
Page 286
LISTING 4-43

xml attribute are case sensitive therefore 4-43 code would fail.

Note from the Author or Editor:
In Listing 4-43 the line: xmlReader.ReadStartElement("Person"); should be changed to: xmlReader.ReadStartElement("person"); And the line: xmlReader.ReadStartElement("ContactDetails"); should be changed to: xmlReader.ReadStartElement("contactdetails");

Audrius Pliksnys  Aug 17, 2013  Oct 11, 2013
PDF
Page 314
2nd paragraph in the chapter "Using DataContract"

"The most noticeable difference is that you use DataContractAttribute instead of SerializableAttribute. Another important difference is that members are not serialized by default. You have to explicitly mark them with the DataMember attribute." Since .NET 3.5 SP1 it is not required - if DataContract and DataMember attributes are not used - only public members are serialized (and some other limitations)

Note from the Author or Editor:
Change: The most noticeable difference is that you use DataContractAttribute instead of SerializableAttribute. Another important difference is that members are not serialized by default. You have to explicitly mark them with the DataMember attribute. To: The most noticeable difference is that you use DataContractAttribute instead of SerializableAttribute. If you omit both the DataContract and DataMember attribute, your public members are serialized. With the DataContract attribute applied, you have to specify which members you want to serialize by using the DataMember attribute on them.

Sergey S  Oct 31, 2013 
Printed
Page 330
Answer 2 D

Objective 4.2 Review answers: Question 2 lists the following possible answers: A. XML Files B. Entity Framework C. ADO.NET D. Web Service However, the answer comment for D(which is marked Incorrect) states the following: "D. Incorrect: The dynamic keyword can be used in scenarios in which you want weak typing. It will still throw errors at runtime if an action is not possible." The comment should refer to why a Web Service is incorrect, and not the dynamic keyword.

Note from the Author or Editor:
Change the explanation for answer D, question 4.2 to the following: A Web service will only move the problem to another layer of your application. Inside the Web service you still have to use some kind of storage to save your application data.

Joakim Svensson  Oct 23, 2013 
Printed
Page 333
Objective 4.5: Objective Review Nr 2, B

Objective 4.5: Objective Review Nr 2, point B states that B is correct. I don't understand why this is correct, because a Queue does not have an Add method.

Note from the Author or Editor:
On page 333 question 2 for Objective 4.5, the answer B should be removed both from the first line and the Correct should be changed to incorrect. Only answer D is correct.

Rudi Janse van Rensburg  Aug 28, 2013  Oct 11, 2013
Printed
Page 333
Objective 4.5: Objective review 1 D

I guess that this is a follow up comment to the confirmed errata reported by Rudi Janse van Rensburg Aug 28, 2013 Objective 4.5: objective review No 1 states that D is correct but I don't understand why this is correct, how can a user easily select an order by its order number in a queue?

Note from the Author or Editor:
On page 333 Objective 4.5 Objective review, the first answer should only have B marked as correct. D should be incorrect.

Anonymous  Sep 19, 2013  Oct 11, 2013