Errata

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
?
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
?
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
?
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, PDF, ePub, Mobi, , Other Digital Version
Page 13
Top

Listing 1-12

See:

http://blogs.msdn.com/b/pfxteam/archive/2012/09/22/new-taskcreationoptions-and-taskcontinuationoptions-in-net-4-5.aspx

Quote from Stephen Toub:

"You?ll notice that the new Task.Run method internally specifies DenyChildAttach when creating its Tasks, in affect making this the default for the API we expect to become the most common way of launching tasks. If you want explicit control over the TaskCreationOptions used, you can instead use the existing Task.Factory.StartNew method, which becomes the more advanced mechanism and allows you to control the options, object state, scheduler, and so on."


It is easy to verify that the parent Task created with Task.Run() does not wait for the child tasks to complete, one could do something like this for the child tasks to verify:

new Task(() => {Thread.Sleep(1000); results[0] = 0;}, TaskCreationOptions.AttachedToParent).Start();
new Task(() => {Thread.Sleep(1000); results[1] = 1;}, TaskCreationOptions.AttachedToParent).Start();
new Task(() => {Thread.Sleep(1000); results[2] = 2;}, TaskCreationOptions.AttachedToParent).Start();


However doing similar with Task.Factory.StartNew instead of Task.Run works as expected.

Note from the Author or Editor:
In Listing 1-12 change the line:
Task<Int32[]> parent = Task.Run(() =>

to:

Task<Int32[]> parent = Task.Factory.StartNew(() =>

Anonymous  Nov 21, 2013 
Printed
Page 13 & 14
listing 1-12 & listing 1-13

lines at end of mentioned listings read:
...
var finalTask = parent.ContinueWith(
parentTask => {
foreach(int i in parentTask.Result)
Console.WriteLine(i);
});
finalTask.Wait();
...
should read
...
var finalTask = parent.ContinueWith(
parentTask => {
foreach(int i in parent.Result)
Console.WriteLine(i);
});
finalTask.Wait();
...
by changing this code the output reads:
0
1
2
instead of
0
0
0
which is what the book wants to achieve and since parentTask (as opposed to the original parent task "parent") has no results.

Note from the Author or Editor:
In Listing 1-14 change:

Task<Int32[]> parent = Task.Run(() =>

to

Task<Int32[]> parent = Task.Factory.StartNew(() =>

Guido D'Alessandro  Mar 18, 2014 
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
PDF
Page 20
Last Paragraph

The last sentence:
If you do something else, such as writing the content to file, you don?t need to set the SynchronizationContext to be set (see Listing 1-21).

I think it should be read something else, maybe like:
If you do something else, such as writing the content to file, you won't get that exceptoption (see Listing 1-21).

Note from the Author or Editor:
On page 20, last paragraph change:

If you do something else, such as writing the content to file, you don?t need to set the SynchronizationContext to be set (see Listing 1-21).

to

If you do something else, such as writing the content to file, you don?t need to set the SynchronizationContext so that won't give an exception (see Listing 1-21).

Ibrahem Khalil  Mar 22, 2014 
PDF
Page 29
Thought Experiment

Author references Task Parallel Library as TPL in the thought experiment, but at no point prior to referring does the author state that TPL = Task Parallel Library.

I suppose it is obvious - but I thought that it was good practice to define acronyms when they are first used).

Note from the Author or Editor:
Change question three in the thought experiment on page 29 to:

Does using multithreading with the Task Parallel Library offer the same advantages for your server application?

Mike Hingley  Dec 20, 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
 
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
 
Aug 05, 2013  Aug 09, 2013
Printed
Page 39
Listing 1-44

I added the line "throw new OperationCanceledException();" after closing the while statement so now my code looks like this

static void Main(string[] args)
{
CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

Task task = Task.Run(() =>
{
while (!token.IsCancellationRequested)
{
Console.Write("*");
Thread.Sleep(1000);
}

throw new OperationCanceledException();

}, token).ContinueWith((t) =>
{
t.Exception.Handle((e) => true);
Console.WriteLine("You have canceled the task");
}, TaskContinuationOptions.OnlyOnCanceled);


Console.ReadKey();
cts.Cancel();
task.Wait();
}

Adding that line solved one problem, but now it still doesn't work because I got a NullReferenceException when I try to get t.Exception object in the continuation task. It works just if I remove the line t.Exception.Handle((e) => true);

Note from the Author or Editor:
Change the code for Listing 1-44 to:

Task task = Task.Run(() =>
{
while (true)
{
token.ThrowIfCancellationRequested();

Console.Write("*");
Thread.Sleep(1000);
}

}, token)
.ContinueWith(t => { Console.WriteLine("You have canceled the task"); },
TaskContinuationOptions.OnlyOnCanceled);

Daniel  Sep 06, 2013 
Printed
Page 42
Listing 1-46

Change Listing title to:

Using the equality operator

Wouter de Kort
Wouter de Kort
 
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
 
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
 
Aug 05, 2013  Aug 09, 2013
Printed
Page 54
2nd paragraph under Jump statements

Goto can only transfer control out of scope not into the nested scope.

So the sentence:
"If the label can't be found or is not within the scope of the goto statement, a compiler error occurs."

Should be changed to:
"If the label can't be found or if the goto statement is not within the scope of the label, a compiler error occurs."

See: http://msdn.microsoft.com/en-us/library/aa664758.aspx

Note from the Author or Editor:
On page 52, second paragraph after heading Jump Statements, change:

If the label can?t be found or is not within the scope of the goto statement, a compiler error occurs.

To
If the label can?t be found or if the goto statement is not within the scope of the label, a compiler error occurs

Dusan Togner  Dec 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
 
Sep 09, 2013  Oct 11, 2013
PDF
Page 102
Table 2-2

Regarding delegate in the description for a constraint on a class:
"The type argument must be a reference type: for example, a class, interface,
delegate, or array."

Example:
class Class1<T>
where T : Delegate
//Error: Constraint cannot be special class 'System.Delegate'

"C# Language Specification":

primary-constraint:class-typeclassstruct

A class-type constraint must satisfy the following rules:
The type must be a class type.
The type must not be sealed.
The type must not be one of the following types: System.Array, System.Delegate, System.Enum, or System.ValueType.

http://stackoverflow.com/questions/191940/c-sharp-generics-wont-allow-delegate-type-constraints

Note from the Author or Editor:
In Table 2-2 change the description of where T : class to:

The type argument must be a class type that's not sealed and not one of the following types: System.Array, System.Delegate, System.Enum, or System.ValueType.

Sergey S  Oct 18, 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
PDF
Page 155
Bullet 1.2

Last sentence in this bullet correctly states "It could be that Dispose is called multiple times and that shouldn?t cause
any errors"

Example in listing 2-84 throws System.Runtime.InteropServices.COMException in operator
Marshal.FreeHGlobal(unmanagedBuffer)
when the Dispose is called more than once. There is another pattern to prevent this with using a field _disposed - which is set to true when the Dispose is called first time.
This can be fixed by "dispose pattern" at http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx

Note from the Author or Editor:
Add the following line to Listing 2-84 right after the line Marshal.FreeHGlobal(unmanagedBuffer);

unmanagedBuffer = IntPtr.Zero;

Sergey S  Oct 18, 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
PDF
Page 165
Listing 2-99

In the if statement the text:

format = "G"

should be:

format == "G"

And shouldn't you trim format before testing whether it is "G"? As it is, entering "G " would throw a FormatException. It might be better to remove the test for "G" from the if statement and add a new case label for "G" to the switch statement. It would be on the same switch section as "FL".

Note from the Author or Editor:
In Listing 2-99 change the line:
if (string.IsNullOrWhiteSpace(format) || format = ?G?) format = ?FL?;
to:
if (string.IsNullOrWhiteSpace(format) || format == "G") format = "FL";

Stephen Richards  Feb 14, 2014 
PDF
Page 174
Objective 2.5: Review, answer 1 A

"The field is a nonstatic instance field."
Is term "instance" correct here? Because the question was not about an instance: "You want to read the value of a private field on a _class_ "?

Note from the Author or Editor:
On page 149, Objective review question 1 change:

You want to read the value of a private field on a class. Which BindingFlags do you need? (Choose all that apply.)

To:

You want to read the value of a private field on a object. Which BindingFlags do you need? (Choose all that apply.)

Sergey S  Oct 18, 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
PDF
Page 176
Objective 2.6: Review. Qu: 2

"Correct: The calling code knows what the lifetime of the object should be and should decide when to dispose of the object."

Please, check the related question again. Because option D in question should be replace with something:
D. No, The calling code knows what the lifetime of the object should be.

Note from the Author or Editor:
Change option D for question 2 on page 176 to:

D. No, the calling code knows what the lifetime of the object should be.

Ibrahem Khalil  Mar 26, 2014 
PDF
Page 188
LISTING 3-9

This line:
if (numberPart.StartsWith(?0?)) return false;
should be moved before:
int number;

Also, your code is not checking whether the characterPart variable contains only letters or not.

Note from the Author or Editor:
Change listing 3-9 to:

private static bool ValidateZipCode(string zipCode)
{
if (zipCode.Length < 6) return false;

string numberPart = zipCode.Substring(0, 4);
if (numberPart.StartsWith("0")) return false;

int number;
if (!int.TryParse(numberPart, out number)) return false;

if (number < 1000) return false;
if (number > 9999) return false;

string characterPart = zipCode.Substring(4).Trim();

if (characterPart.Trim().Length != 2) return false;

foreach (char c in characterPart)
{
if (!char.IsLetter(c)) return false;
}

return true;
}

Ibrahem Khalil  Mar 27, 2014 
Printed
Page 189
Listing 3-11

Change listing title to:

Collapse multiple spaces with RegEx

Wouter de Kort
Wouter de Kort
 
Aug 05, 2013  Aug 09, 2013
PDF
Page 194
Last Paragraph

The sentence: "Asymmetric encryption is not optimized for encrypting long messages, but it can be very useful for decrypting a small key."
- decrypting word should be encrypting

Note from the Author or Editor:
On page 194 in the last paragraph change:

Asymmetric encryption is not optimized for encrypting long messages, but it can be very useful for decrypting a small key.

to

Asymmetric encryption is not optimized for encrypting long messages, but it can be very useful for encrypting a small key.

Ibrahem Khalil  Mar 27, 2014 
Printed
Page 195
last paragraph

The book says:
All cryptography classes can be found in System.Security.Cryptography class.

Should be:
in System.Security.Cryptography namespace.

Note from the Author or Editor:
Change last sentence on page 195 from:

All cryptography classes can be found in the System.Security.Cryptography class.

to

All cryptography classes can be found in the System.Security.Cryptography namespace.

Anonymous  Jan 05, 2014 
PDF
Page 195
Step 3

The sentence: "They both generate a symmetric key and encrypt it only with the other parties? public key (so that it can be encrypted by the private key of the other person).
- The last "encrypted" word should be decrypted.

Note from the Author or Editor:
Point 3 on page 195 should read:

They both generate a symmetric key and encrypt it only with the other parties? public
key (so that it can be decrypted by the private key of the other person).

Ibrahem Khalil  Mar 27, 2014 
PDF
Page 200
Listing 3-22

The following method can be removed since it is not used in the example.

public bool Contains(T item)
{
return Contains(item, GetBucket(item.GetHashCode()));
}

Note from the Author or Editor:
The following lines can be removed from Listing 3-22:

public bool Contains(T item)
{
return Contains(item, GetBucket(item.GetHashCode()));
}

Anonymous  Jan 09, 2014 
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 
PDF
Page 202
Last paragraph

After generating a file with a certificate:
"You first need to install this certificate on your computer to be able to use it."

It was confusing due to following lines does not tell how to use the file testCert.cerf. Does installation of a certificate somehow relates to this generated file?

Note from the Author or Editor:
Change the last paragraph on page 202 from:

This command generates a file called testCert.cer that you can use as a certificate. You first need to install this certificate on your computer to be able to use it. After installation, it?s stored in a certificate store. The following line creates a certificate and installs it in a custom certificate store named testCertStore:

to:

This command generates a file called testCert.cer that you can use as a certificate.
You can install this certificate by using CertMgr. However, it's easier to create and install the certificate in one go. The following line creates a certificate and installs it in a custom certificate store named testCertStore:

Sergey S  Oct 18, 2013 
PDF
Page 203
Listing 3-24

operator
byte[] signature = Sign(textToSign, ?cn=WouterDeKort?);
method
static byte[] Sign(string text, string certSubject)

The parameter certSubject is not used. It can be found following way:

var certCollection = x509Store.Certificates
.Find(X509FindType.FindBySubjectName, subjectName, false)
.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
return certCollection.Count > 0? certCollection[0]: null;

Where subjectName is case insensitive, should not contain "cn=".
E.g. if subjectName="testcert" it finds:
"CN=TestCert"
"CN=TestCert123"
"CN=MyTestCert"

Note from the Author or Editor:
Change the line:
byte[] signature = Sign(textToSign, "cn=WouterDeKort");

to

byte[] signature = Sign(textToSign);

And
private static byte[] Sign(string text, string certSubject)
to
private static byte[] Sign(string text)

Sergey S  Oct 18, 2013 
PDF
Page 209
Question 3

X509Certificate2 does not have SignHash method. So no answer can be correct.

You must use private key which is (RSA,DSA)CryptoServiceProvider and this object has Sign(Verify)Hash method - as example 3-24.

Note from the Author or Editor:
Change option A Question 3 on page 209 to:

RSACryptoServiceProvider.SignHash

The answer on page 248 for option A should be changed to:

Using the digital certificate X509 you can get a private key of type RSACryptoServiceProvider which can be used to sign hashed data. If the other party uses the Verify method, it can check that the hash hasn?t changed.

Petr  Mar 11, 2014 
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 
PDF
Page 230
Thought experiment

The first bullet (1. ) should be removed to be part the last sentence in the preceding paragraph.
Also, 2, 3, 4 bullets should be renamed to be 1, 2, 3 respectively.

Note from the Author or Editor:
On page 230, in the thought experiment, remove the 1 before 'You want' and make sure that 2,3,4 become 1,2,3

Ibrahem Khalil  Mar 28, 2014 
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
Printed
Page 247
Objective 3.1 Review

In the errata the "Note from the Author or Editor" to the error report submited by Daniel D Aug 12 2013 is not correct. Daniels comment about the answers to question 3 is still valid. There is no answer to the question about validating an xml file.which is question 3.

Note from the Author or Editor:
The answer to question 3 in objective 3.1 is missing. Add the following answer on page 247

3 Correct answer: D
A. Incorrect: The JavaScript serializer is used to serialize and deserialize objects from and to JSON. It's used in AJAX applications.
B. Incorrect: Although RegEx is suited for validating strings, validating a complete XML document with a RegEx is undoable.
C. Incorrect: StringBuilder is used to construct a string at runtime without constructing a new string in memory each time you make change.
D. Correct: An XSD is used to validate the schema of an XML file.

Anonymous  Oct 03, 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
Printed
Page 254
Listing 4-1

In Listing 4-1

Console.WriteLine(" File type: ...

should be changed to

Console.WriteLine(" Drive type: ...

Note from the Author or Editor:
In listing 4-1 change:

Console.WriteLine(? File type: {0}?, driveInfo.DriveType);

To

Console.WriteLine(? Drive type: {0}?, driveInfo.DriveType);

Norbert Nolte  Dec 04, 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
PDF
Page 265
Listing 4-22

Why not change the code in listing 4-22 to:
WebRequest request = WebRequest.Create("http://www.microsoft.com");
using (WebResponse response = request.GetResponse())
{
using (StreamReader responseStream = new StreamReader(response.GetResponseStream()))
{
var responseText = responseStream.ReadToEnd();
Console.WriteLine(responseText);
}
}

It takes up 9 rows, the same as the code in the listing. This would close the resources as its done in e.g. Listing 4-19.

Note from the Author or Editor:
Change listing 4-22 to:

WebRequest request = WebRequest.Create("http://www.microsoft.com");
using (WebResponse response = request.GetResponse())
{

using (var responseStream = new StreamReader(response.GetResponseStream()))
{
string responseText = responseStream.ReadToEnd();
Console.WriteLine(responseText);
}
}

Anonymous  Jan 09, 2014 
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 286
Listing 4-43

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

It should change the next line:

xmlReader.ReadStartElement("People");
To
xmlReader.ReadStartElement("people");

Note from the Author or Editor:
The code of listing 4-43 should be changed to:

string xml = @"<?xml version=""1.0"" encoding=""utf-8"" ?>
<people>
<person firstname=""john"" lastname=""doe"">
<contactdetails>
<emailaddress>john@unknown.com</emailaddress>
</contactdetails>
</person>
<person firstname=""jane"" lastname=""doe"">
<contactdetails>
<emailaddress>jane@unknown.com</emailaddress>
<phonenumber>001122334455</phonenumber>
</contactdetails>
</person>
</people>";

using (var stringReader = new StringReader(xml))
{
using (XmlReader xmlReader = XmlReader.Create(stringReader,
new XmlReaderSettings {IgnoreWhitespace = true}))
{
xmlReader.MoveToContent();
xmlReader.ReadStartElement("people");

string firstName = xmlReader.GetAttribute("firstName");
string lastName = xmlReader.GetAttribute("lastName");

Console.WriteLine("Person: {0} {1}", firstName, lastName);
xmlReader.ReadStartElement("person");

Console.WriteLine("ContactDetails");

xmlReader.ReadStartElement("contactdetails");
string emailAddress = xmlReader.ReadString();

Console.WriteLine("Email address: {0}", emailAddress);
}
}

Francisco  Dec 16, 2013 
PDF
Page 304
LISTING 4-68

To be able to run through the foreach loop
"Person" has to changed to "person":
from
foreach (XElement p in root.Descendants(?Person?))
to
foreach (XElement p in root.Descendants(?person?))

To get ismale=true on johndoe change "John" to "john:
from
p.Add(new XAttribute(?IsMale?, name.Contains(?John?)));
to
p.Add(new XAttribute(?IsMale?, name.Contains(?john?)));

Why not add ToLower() in the mix:
p.Add(new XAttribute(?IsMale?, name.ToLower().Contains(?john?)));

The new attributes should perhaps be
"contactdetails" instead of "ContactDetails" and
"phonenumber" instead of "PhoneNumber"

Note from the Author or Editor:
Change Listing 4-68 to:

XElement root = XElement.Parse(xml);

foreach (XElement p in root.Descendants("person"))
{
string name = (string) p.Attribute("firstname") + (string) p.Attribute("lastname");
p.Add(new XAttribute("ismale", name.Contains("john")));
XElement contactDetails = p.Element("contactdetails");
if (!contactDetails.Descendants("phonenumber").Any())
{
contactDetails.Add(new XElement("phonenumber", "001122334455"));
}
}

Anonymous  Jan 15, 2014 
PDF
Page 306
Objective 4.3: Objective Review 2 - B, D

You have a list of dates. You want to filter the dates to the current year and then select the highest date. Which query do you use?
A.
DateTime result = dates.Where(d => d == DateTime.Now).OrderBy(d => d).First();
B.
DateTime result = dates.Where(d => d.Year == DateTime.Now.Year).OrderByDescending(d => d).FirstOrDefault();
C.
DateTime result = dates.Where(d => d.Year == DateTime.Now.Year).OrderByDescending(d => d).First();
D.
DateTime result = dates.Where(d => d.Year == DateTime.Now.Year).OrderByDescending(d => d).Single();

-----------------------------------------------------------------------------------

By Book: B,D

A. Incorrect: Comparing DateTime.Now to the dates will give you only the dates for
today, not for the whole year. Also, using OrderBy instead of OrderByDescending
will give you the lowest date, not the highest.
B. Correct: This will return the highest date for the current year. If your filter can?t
find a value for the current year, it will return ?1-1-0001 00:00:00? (DateTime.Min-
Value).
C. Incorrect: If your filter doesn?t return a value, you will get an error. You should use
FirstOrDefault instead.
D. Correct: Using Single will throw an exception if there are multiple dates for the
current year.

-----------------------------------------------------------------------------------

I guess, that right answer is only C. (B and D are incorrect)

C is correct because:
It returns only item with current year, but it don't return default value, which it haven't been required

B is incorrect becase:
It returns default value if don't exist any result.
(But in question don't want default value, they want only current year)


And answer D is incorrect too, becase:
If expression method Where returns more results, so Single expression throw error, so we don't get any result.





Note from the Author or Editor:
On page 331, question 1 only has one good answer: B

Change option D to start with Incorrect

Tom  Mar 18, 2014 
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