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.
Version |
Location |
Description |
Submitted By |
Date submitted |
Date corrected |
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 |
|
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 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 |
|
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 |
|
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 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 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 |
|
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 |
|
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 |
|
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 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 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 |
|
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 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 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 |
|
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 |
|
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 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 |
|
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, 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 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 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 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 |
|
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 |
|
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 |
|
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 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 |
|
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 |
|
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 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 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 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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 |
|
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 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 |
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 |
Sep 09, 2013 |
Oct 11, 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 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 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 |
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 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 |
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 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 |
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 |
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 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 |
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 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 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 |
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 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 |
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 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 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 189
Listing 3-11 |
Change listing title to:
Collapse multiple spaces with RegEx
|
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 |
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 |
Aug 05, 2013 |
Aug 09, 2013 |
Printed |
Page 42
Listing 1-46 |
Change Listing title to:
Using the equality operator
|
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 |
Aug 05, 2013 |
Aug 09, 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 |
Aug 05, 2013 |
Aug 09, 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 |
|
?
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 |
|
?
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 |
|
?
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 |