The SLAR on System.Console

More from the series sharing some of the information in the .NET Framework Standard Library Annotated Reference Vol 1 here is an annotation from the System.Console attribute.


Brad Abrams:

Notice the heavy use of method overloading in this class. We special-case each

of the primitive types in order to avoid boxing overhead. We could have gotten away

with just having the overload that takes the object, but then calls such as these would

cause an extra allocation for the coercion to object:

Console.WriteLine (42);


Console.WriteLine (‘c’);

In general this kind of special casing is not necessary, but for a class that is likely to be

used in a tight loop it can be very helpful.

This class is a classic example of “design in reverse.” Before we designed this class we

knew what we wanted the Hello World example to look like:

Console.WriteLine (“Hello World”);

We then created this class to make that sample code a reality. Even in the face of the

full complexity of a well-factored I/O system, we kept the simple things simple.


Anders Hejlsberg:

It is interesting to note that all of the Console.WriteXxx() methods are just

shorthand for Console.Out.WriteXxx(). Likewise, Console.ReadXxx() is

shorthand for Console.In.ReadXxx(). This design enables the In and Out

streams to be available directly in the rare cases where they are needed but does not

complicate the simple usage with them.


Brian Grunkemeyer

The OpenStandardXxx methods that take an integer for the buffer size are

really rather useless. We eventually decided that supporting buffering on the streams

used for Console is a silly notion, especially since classes like StreamReader and

StreamWriter may internally do their own buffering.


Kit George

Note that there is no easy way for a user to get a single key press: Return has to

be pressed before Read or ReadLine complete. This did not seem like a critical scenario

when we designed this class originally, but it is interesting to note that this has

been one of our top requests for the Console class since Version 1 was released.



Comments (7)

  1. Robert Taylor says:

    looks like something got cut off. "but it is interesting to note that this has…" has what?

  2. Ahh — that is the bit you have to buy the book to find out what it says.. 😉

    No really, my mistake, I will fix it.

  3. Hugh says:

    I couldn’t find a way to check whether Console.In really is the (interactive) console, or a redirected file or pipe, without resorting to GetStdHandle and GetFileType dllimports from Kernel32.dll. (For the "rare cases when they’re needed", it’s often useful to know whether reading from the inputstream will block)

  4. Rico Mariani says:

    >>Notice the heavy use of method overloading in this class. We special-case each of the primitive types in order to avoid boxing overhead.

    Sadly the savings are only at the first level. All of these functions end up merging in a general helper that does the formatting later in the call sequence. This is kind of too bad because we end up boxing where we could have avoided but all is not lost. By doing it the way we did we left the door open to fixing this in later versions. The IL in the code you write is doing it the good way and any boxing was moved into our libarary.

    Read Performance Quiz #1 at for more detais on this.

  5. Joe Duffy says:

    Also note that KitG’s comments are no longer valid for Whidbey. As most are probably aware, Console’s received a great facelift with 2.0… Part of that (aside from color support 🙂 ) is Console.ReadKey(), which returns a ConsoleKeyInfo struct. This has pretty much all the info you’d ever need, like the key pressed, any modifiers (Alt, Control, Shift), and so on.

  6. Timothy Fries says:

    >> it’s often useful to know whether reading from the inputstream will block

    It’s also interesting to note that calling BeginRead on the standard input stream the Console class gives you *will* block, contrary to what you’d expect. As far as I can tell, it’s effectively impossible to do asynchronous I/O to the console without having to dedicate a whole thread to it.

Skip to main content