Sorry if I wasn't clear, some of these (p5, 9...) are just comments for which I don't expect you to change a single word smilie

The brackets' issue is a problem of indentation, for instance:

  public T Value
      if (!hasValue)
        throw new InvalidOperationException();
      return value;

First of all thanks a lot for putting this together, C#2 brings back lots of good memories smilie

Page 5 How to construct delegates relatively easily1 (1 as a digit)

Page 5 For me the answer to this one is simple: C# 1 was a more productive language for many developers than Java was at the time.
Isn't it also because it was one of the languages of choice for .net development?
I was doing Delphi/C++ when .net was released and to me the transition to C# was natural in a Windows environment.

Page 9 I’m deliberately not going into the possibility of using interfaces for return types and parameters. That’s an interesting topic, but I don’t want to be distracted
from generics.
Definitely and interesting topic, it would be nice to have a section on this with the pros/cons of each possibility
(IEnumerable<T> and its potential performance traps in case GetEnumerator is called more than once, IReadOnlyList...)

page 24 Code formatting (curly brackets)

page 25: Enum itself isn't a value type either

page 25 Code formatting (curly brackets)

page 25: it also comes from making it harder to write broken code

Page 26: only place we’ve seen where the CLR needs understand Nullable<T> is to enforce the struct type constraint:
I guess by struct type constraint you mean the way the compiler constrains nullable types rather than `where T: struct`?

page 29: C# 7 has an even better solution for most cases where I’ve used the as operator with nullable value types.
But you can't use pattern matching with nullable types, can you?
If the value is null then there's nothing to match against and if it is not null, you can match against the underlying type instead of the nullable type.

page 34: For reference, EventHandler is has a signature of

page 35: Method group conversions save a few characters when create(ing?) a delegate instance (ing)

page 47: Code formatting (curly brackets)

page 56: you can then use then use
I've just finished it and my head hurts a little bit smilie

I've found these

Page 144
The control flow is very simply

Page 152
This intricate dance ensures that when the a continuation delegate is passed
Page 124
That’s explains how

Page 133 Not a typo but I think by
void method
you usually mean a method returning void. In this case, shouldn't
would be that SetResult would be a void method
be "would be that SetResult would be parameterless"?
(In the latest edition, v11)

Just in case these have not been spotted by the correctors:

Page 111:
public bool IsCopmleted { get; }

Page 117: If this we using synchronous calls
Congrats for the chapter on asynchrony, which clearly describes the actual benefits of it. I'm looking forward chapter 4.

Be aware that if hourlyRateTask fails, you won’t see be checking the result of hoursWorkedTask.

Also, there a few hyphens in class names in this chapter, not sure it's intended:

public interface IEnumerable
    IEnumerator GetEnumerator();

    int Count()
        using (var iterator = GetEnumerator())
            int count = 0;
            while (iterator.MoveNext())

            // The following line is missing in the book
            return count;

Can default interface properties be defined too?
Not sure about this one but

Unlike ref and out parameters, there’s no mention of in at the call-site (i.e. whether the
method is called)

should probably be

Unlike ref and out parameters, there’s no mention of in at the call-site (i.e. where the
method is called)
OK thanks
Input didn't match hello, int 5 or long 010

should be

Input didn't match hello, int 5 or long 10

BTW do you have any idea why the comparison is done using == only for integer types and not for other primitive .net types like System.Boolean or System.Double?
Yet again, this is a feature doesn’t allow you to do anything you couldn’t do before

should probably be

Yet again, this feature doesn’t allow you to do anything you couldn’t do before

OK thanks
, I can still see it on the current MEAP pdf:

(each of which would be in a separate implementation class, of coruse

but as you said it will probably be fixed later

Concerning the paragraph formatting, I'm not sure if you intended to show 'arities' as code. In
with arity 9
for instance,
with arity
is formatted as text and 9 as code.
or a
is also formatted as code but maybe it's just me being in [superpicky][/superpicky] mode

(I can send you a screen capture if needed)
(based on the MEAP v05)

Page 101:
of coruse
instead of
of course

Page 109:
… could be treated as a C#-syntax type (A, B, C, D, E, F, G, H, I) with arity 9, or a
type (A, B, C, D, E, F, G, (H, I)) with arity 8 and the final element being a tuple
the code / non code blocks formatting looks weird

Chapter 9: It's a tiny thing but
is sometimes formatted
arity x

if (!iterator.MoveNext())
    throw new InvalidOperationException( 
       "Cannot find min/max of an empty sequence");

Should probably be

if (!iterator.MoveNext())
    throw new InvalidOperationException( 
       "Cannot find min/max of an empty sequence");

Hi Jon

Thanks a lot for keeping C# in depth up to date

On page 72, shouldn't

string authorName = book.Element(author)?.Attribute("name")?.Value;


string authorName = book.Element("author")?.Attribute("name")?.Value;