The errata list is a list of errors and their corrections that were found after the product was released.
The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.
Version |
Location |
Description |
Submitted by |
Date submitted |
Printed |
Page xxiv
2nd paragraph |
The link for the program source code with examples to the book
http://wintellect.com/Books
doesn't work -- "404 Not Found" error
Use this one instead:
http://wintellect.com/Resource-CLR-Via-CSharp-Fourth-Edition
|
Yury Shpakov |
Aug 01, 2013 |
Printed, PDF, ePub |
Page 10
Table 1-2 |
Chapter 1 Part 1 in the Table 1-2
It shows that the default is anycpu, which is not correct since in VS 2013 the default is anycpu32bitprefered.
Reference http://blogs.microsoft.co.il/blogs/sasha/archive/2012/04/04/what-anycpu-really-means-as-of-net-4-5-and-visual-studio-11.aspx
|
colin fang |
May 15, 2013 |
PDF |
Page 20
3rd paragraph, first point |
"Unfortunately, this is not possible. At run time, the CLR requires access to the assembly?s metadata... this requires that the assemblies that contain IL and metadata be shipped."
Starting with .NET version 2.0, the native image generator includes the IL code and metadata in the native image together with native code. The justification provided in the book holds only in .NET 1.0 and 1.1. It should something like "Unfortunately, this is not possible because the IL code is still included in the native image".
|
Hadi Brais |
Dec 22, 2013 |
Printed, PDF |
Page 40
TABLE 2-2, TypeRef row (head of page #40) |
It's not a mistake, I just want to note something.
Quoted from the book:
"Metadata Reference Table Name: TypeRef
Description: Contains one entry for each type referenced by the module. Each entry includes the type?s name and a reference to where the type can be found. [...] If the type is implemented in the same module, the reference will indicate a ModuleDef entry. [...]"
According the ECMA-335, 6th edition, section II.22.38 "TypeRef : 0x01" at informative text section 1.d describing the ResolutionScope index, the ModuleDef table should not be referenced by the TypeRef table.
"a Module token, if the target type is defined in the current module - this should not occur in a CLI (?compressed metadata?) module [WARNING]"
The book states that "the reference will indicate a ModuleDef entry", but the CLR isn't, and shouldn't support that (valid somehow) option according the CLI standard.
|
Tamir Shlomi |
Nov 18, 2013 |
PDF |
Page 71
important note |
"Note, however, that the CLR never uses public key tokens when making security or trust decisions because it is possible that several public keys could hash to a single public key token."
So assume that we have two assemblies with identical display names (name, version, culture, public key token) but signed with different public/private key pairs. Is it possible to install both of them in the GAC? Is it possible to reference both of them from the same assembly? Considering the following cases:
1- Both are globally deployed. Both are DLLs.
2- Both are globally deployed. One is a DLL and the other is an EXE.
3- Both are privately deployed to the same directory. Same file names but different extensions.
4- Both are privately deployed to the same directory. Different file names where both of these name are different from the assembly name.
4- Both are privately deployed to the same directory. Different file names where only one of the names matches the assembly name.
|
Hadi Brais |
Dec 24, 2013 |
PDF |
Page 75
fourth paragraph |
"In addition, the assemblies in the compiler/CLR directory are machine agnostic. That is, these assemblies contain only metadata in them."
However, when opening an assembly from the compiler/CLR directory using ildasm.exe, we can clearly see that this assembly contains the IL code in it, not only metadata.
|
Hadi Brais |
Dec 24, 2013 |
Printed, PDF |
Page 81
second section "Different file, same assembly" |
"The runtime ensures that the file being referenced is, in fact,
in the assembly?s ModuleRef table of the current assembly?s manifest"
Instead of "assembly?s manifest" it should be "assembly?s metadata" as the ModuleRef is defined at the metadata and not at the manifest.
|
Tamir Shlomi |
Nov 09, 2013 |
Printed, PDF |
Page 83
First paragraph |
"When searching the GAC for an assembly, the CLR figures out that type of process the application is currently running in: 32-bit x86 (possibly using the WoW64 technology), 64-bit x64, or 32-bit ARM."
"32-bit x86" (the first type listed) process type isn't require the WoW64 as it should run naturally.
Maybe the author meant to "32-bit x64" where the WoW64 is used to run 32-bit process over x64 machine as mentioned at the parenthesis right after.
|
Tamir Shlomi |
Nov 10, 2013 |
PDF |
Page 92
Table 4-1, GetType |
"Returns an instance of a Type-derived object that identifies the type..."
It should be"Returns an instance of a Type-derived type that identifies the type..."
|
Hadi Brais |
Dec 25, 2013 |
PDF |
Page 93
1st paragraph |
"After new has performed all of these operations, it returns a reference (or pointer) to..."
Why "(or pointer)"? Maybe you are trying to say "(which could be implemented as a pointer)".
|
Hadi Brais |
Dec 25, 2013 |
PDF |
Page 108
How THings Relate at Run Time: 2nd paragraph of the page |
"The next line of code in M3 calls Employee?s nonvirtual instance GetYearsEmployed method. When calling a nonvirtual instance method, the JIT compiler locates the type object that corresponds to the type of the variable being used to make the call. In this case, the variable e is defined as an Employee. (If the Employee type didn?t define the method being called, the JIT compiler walks down the class hierarchy toward Object looking for this method.)
Also in page 163
When the call instruction is used to call an instance or virtual method, you must specify a variable that refers to an object. The type of the variable itself indicates which type defines the method that CLR should call. If the variable's type doesn't define the method, base types are checked for a matching method.
As far as I am aware, in non-virtual instance method, C# resolves the exact method and encode it into IL as the method descriptor after the call IL instruction. JIT determines the method address entirely from the method descriptor (which contains the type as well as the method signature).
So, I don't get how the variable type comes into play, is it taken from the static type of the instance reference that gets pushed into the execution stack as the first argument of the call instruction? I don't think JIT would ignore the type name in the method descriptor and look for the method signature from the method table of the variable type object, or would it?
As your book is the only definitive guide I can find, please clarify a little bit.
Reference:
http://stackoverflow.com/questions/4909373/is-richter-mistaken-when-describing-the-internals-of-a-non-virtual-method-call
http://stackoverflow.com/questions/17808622/how-is-non-virtual-instance-method-inheritance-resolved
|
colin fang |
Jul 23, 2013 |
Printed |
Page 134
3rd commented line in Program::Main() |
The following comment,
// p DOES get boxed to call GetType (a non-virtual method)
should probably instead be the following:
// p1 DOES get boxed to call GetType (a non-virtual method)
Otherwise, this does not make sense, as there is no "p".
|
Veronica Dancer |
Feb 24, 2014 |
PDF |
Page 150
Pakistan |
on page 150 dynamic types
Error in TryInvokeMember method mistake is
Wrong:
MethodInfo method = FindMethod(binder.Name);
Correct:
MethodInfo method = FindMethod(binder.Name,args.Select(c=>c.GetType()).ToArray());
|
Anonymous |
Jun 07, 2013 |
PDF |
Page 156
The paragraph preceding table 6-1 |
"Table 6-1 shows the six accessibility modifiers that can be applied to a member. The rows of the table are in order from most restrictive (Private) to least restrictive (Public)."
Firstly, "Family and Assembly" is more restrictive than "Family" and so they are not in the right order in the table. Secondly, "Family" and "Assembly" cannot be ordered because we cannot say that one is more restrictive than the other.
|
Hadi Brais |
Dec 26, 2013 |
PDF |
Page 164
last paragraph |
"In some other programming languages, the intention of the following code would run just fine."
In some other programming languages, the following code would run just fine.
|
Hadi Brais |
Dec 26, 2013 |
|
255
Chapter 11. Events -> Designing a Type That Exposes an Event -> Step #3 |
The definition of the extension method "Raise" is incomplete. If you try to compile it, you get following error: "The type 'TEventArgs' must be convertible to 'System.EventArgs' in order to use it as parameter in the generic delegate 'delegate void EventHandler<TEventArgs>(object sender, TEventArgs e)'."
In the previous part of the chapter it is said that it's only an convention:
"By convention, classes that hold event information to be passed to the event handler should be derived from System.EventArgs"
So when we want to use a generic version of EventHandler it is a must (where TEventArgs : System.EventArgs).
|
Adam Sitnik |
Mar 24, 2014 |
PDF |
Page 257
Code example |
Code for add_NewMail & remove_NewMail methods uses "newMail != prevHandler" as the loop exit condition.
As the Delegate type redefines "==" & "!=" operators, this test will result in Delegate's "Equals(object)" (costly) override being called, whereas a simple call to object.ReferenceEquals(newMail,prevHandler) would be OK.
So dont' you think the loop should be rewritten like this?
do
{
}
while(!object.ReferenceEquals(newMail, prevHandler))
|
Denis Ducansel |
Nov 28, 2013 |
PDF, ePub, Mobi |
Page 417
code sample |
using System;
using System.Reflection;
using System.IO;
(snip)
// This callback method takes 1 String argument
private static Object Reverse(String s1) {
return new String(s1.Reverse().ToArray());
}
I think you missed to add "using System.Linq;".
The sample uses the reverse() Methord without specifying "using System.Linq" namespace. Thus, the following line should be added
|
kkamegawa |
Jul 08, 2013 |
PDF |
Page 493
code sample at the bottom |
the second overload is written as follows:
public static Boolean TryParse(String s, NumberStyles styles, IFormatProvider, provider, out Int32 result);
notice the comma after IFormatProvider. I believe it shouldn't be there: 'IFormatProvider' is a type of the parameter and 'provider' is its name.
|
Anonymous |
Feb 16, 2014 |
PDF |
Page 657
Last a code sample |
IInputStream interface defined as follow.
But showed IOutputStream.
Correct is follow.
public interface IInputStream : ICloseable{
IAsyncOperationWithProgress<UInt32, UInt32> ReadAsync(IBuffer buffer, uint count, InputStreamOption options)
}
|
Shozo Arai |
Jul 23, 2013 |
Printed |
Page 705
2nd paragraph, 2nd sentence |
The following statement doesn't seem to follow from any preceding text in the chapter:
"... calling Wait or querying a task's Result property when the task has not yet finished running will most likely cause the thread pool to create a new thread..."
Is an explanation of internals missing?
|
Anonymous |
May 25, 2013 |
Printed |
Page 705
Code sample, first comment. |
The comment:
// This tasks creates...
should probably be:
// This task creates...
|
Anonymous |
May 25, 2013 |
Printed |
Page 743
First paragraph |
It would have been helpful if the asynchronous patterns discussed in this chapter (TAP, APM, EAP) were mentioned by name.
|
Anonymous |
May 27, 2013 |
PDF |
Page 791
2nd paragraph |
In the fifth line, "On the other hand, if the thread calling Leave sees that m_waiters was not 1"
should be "the thread calling Leave sees that m_waiters was not 0, then the thread knows that there is contention and that there is at least one other thread blocked in
the kernel"
|
Xiaokun Zhang |
Dec 08, 2013 |
PDF, ePub |
Page 802
A paragraph before a bullet list and a bullet list ifself |
In 4th edition, a description of OneManyLock is updated and it states that OneManyLock now uses Int64 fields and supports 20bit size readers/writers. However, source code provided in author's web site (http://wintellect.com/Resource-CLR-Via-CSharp-Fourth-Edition) still uses Int32 fields as 3rd edition.
|
Yusuke Fujiwara |
Sep 08, 2013 |
Other Digital Version |
3032
Table 5-1. C# Primitives with corresponding FCL Types |
Kindle edition. Location 3032. "Chapter 5. Primitive, Reference, and Value Types"
The table 5-1 mentions that string, object and dynamic are primitive types.
According to the following code, string and object are not primitive types:
Console.WriteLine("Is {0} a primitive data type? {1}.", typeof(string).Name, typeof(string).IsPrimitive);
Console.WriteLine("Is {0} a primitive data type? {1}.", typeof(object).Name, typeof(object).IsPrimitive);
This MSDN page is listing the primitive types: http://msdn.microsoft.com/en-us/library/system.type.isprimitive(v=vs.110).aspx
|
Gabriel Weyer |
Nov 09, 2013 |