Errata

CLR via C#

Errata for CLR via C#

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.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

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