In this article, we are going to talk about the Console class in C# and inspect the different methods and properties this class contains.
The Console class is the first thing that most people see when creating a C# Console Application:
// See https://aka.ms/new-console-template for more information Console.WriteLine("Hello, World!");
However, there’s much more to this class. In this article, we’ll discuss the basic and more advanced features of the class.
What is The Console Class
The Console class is a static class that’s provided as part of the System namespace. What that means is that, as a static class, it cannot be inherited, it does not implement an interface and therefore is difficult to mock out for tests, and it does not need to be instantiated. The class functions (or tries to function) as an input and output interface; for example, the previous code sample outputs Hello, World! to the console, but the output text can be redirected to a file on the hard drive. Additionally, since it’s part of the System namespace, a Console Application is not the only place that it can be used.
How To Use The Console Class in C#
Now that we’ve discussed what the Console Class is, let’s explore what it can do. We’ll start with some basic functionality, and then move through to some more complex examples.
Accepting Input
The first category is a very simple use case, and after the Hello, World! example, it’s probably the next thing someone may come across when learning C#:
Console.WriteLine("What is your name?"); string name = Console.ReadLine(); Console.WriteLine($"Hello, {name}");
With the ReadLine
method, we are accepting the input from our users.
This is great for learning the basics, but ReadKey
may be more useful. Console apps are excellent for proof of concepts; let’s imagine that we’re creating such an app that has more than one mode – a menu system can easily be added:
Console.WriteLine("1 - Hello World"); Console.WriteLine("2 - Ask Name"); var result = Console.ReadKey(); switch (result.Key) { case ConsoleKey.D1: Console.WriteLine("Hello, World!"); break; case ConsoleKey.D2: Console.WriteLine("What is your name?"); string name = Console.ReadLine(); Console.WriteLine($"Hello, {name}"); break; }
ReadKey
doesn’t wait for the Enter key to be pressed; we can go even further with this basic functionality, for example, we could use this to write a game inside a console application.
A close cousin of ReadKey
is Read
:
int test = Console.Read(); Console.WriteLine(test);
This is kind of a hybrid between ReadKey
and ReadLine
. This reads a single character at a time from the input stream, and it returns the ASCII value of that character. For example, if we run the code, typing asdf (followed by Enter – the program execution blocks until the Enter key is pressed on a standard input stream) outputs 97 (the ASCII decimal code for “a”).
If we add another Read
to the code, it will print the ASCII code for the first two characters:
var test = Console.Read(); var test2 = Console.Read(); Console.WriteLine(test); Console.WriteLine(test2);
Output
We’ve already seen the basics of displaying output, but there are actually a number of things that we can do to improve this experience. For example, the color can be changed:
Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Hello, World!"); Console.ResetColor();
Note the call to ResetColor
here; this is important because the color doesn’t automatically reset itself, meaning that, if the color is set to black, we effectively stop the output showing in the console.
We can also change the color within the same session:
public static async Task ShowColorsRotate() { for (int i = 2; i < 10; i++) { await Task.Delay(1000); Console.Clear(); Console.ForegroundColor = (ConsoleColor)i; Console.WriteLine("Hello, World!"); } Console.ResetColor(); }
This will iterate some of the available colors. Note here the use of Console.Clear
, which clears the current text within the console.
It’s also possible to control the height of the window and the buffer:
Console.WindowHeight = 10; Console.BufferHeight = 30; for (int i = 0; i < 100; i++) Console.WriteLine($"Line {i}");
This allows the buffer (that is, the amount of output that’s retained in memory) to be anywhere between the window height (the physical height of the console) and int.MaxValue
.
There are some libraries that will do some of this work around the console output for us, an example of which is Spectre.
Output is not limited to visual output, although the audio capabilities of the Console class are limited:
Console.Beep(500, 1000); await Task.Delay(50); Console.Beep(1000, 500); Console.Beep(1500, 500); Console.Beep(1200, 500); Console.Beep(200, 600); Console.Beep(1000, 500);
There are places on the internet that have coherent tunes made using this function. It’s worth bearing in mind that, whilst most of the Console class is cross-platform, this method is not, and will only work on Windows.
Where To Use The Console Class
As we’ve already seen, the console class can be used in a console application. Whilst you may think that a console application is a specific, and commercially unlikely type of application, it’s worth bearing in mind that a self-hosted Kestrel application is, essentially, a console app. In a new Razor Pages web app, we can prove this by adding the following code to the PrivacyModel
:
public void OnGet() { Console.WriteLine("test"); }
Navigating to the Privacy Page, the console message output can be seen. The same is true for other types of self-hosted web apps, Azure Function Apps, and others.
When and Why To Use The Console Class
The Console Class works well when running in a Console Application. The input and output can also be changed; for example, the following code reads from a text file and writes the contents to another file:
var outputLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var file = $"{outputLocation}/SampleFile/test.txt"; using TextWriter tw = File.CreateText(file); using TextReader tr = new StreamReader($"..."); Console.SetIn(tr); Console.SetOut(tw); string result = Console.ReadLine(); Console.WriteLine(result);
Of course, this is just a simple example that does nothing specific. But the idea can be used for logging, or streaming data into, or out of the application; it can also be used for testing.
Conclusion
The Console class has far more reach and functionality than it may be given credit for. Whilst it probably makes sense to restrict its usage to a simple proof of concept applications, that is, by no means, its limitation.