Breaking Down a Simple C# Program

namespace Chapter_3 
{ 
    internal class SimpleCSharpApp 
    { 
        static void Main(string[] args) 
        { 
            Console.WriteLine($"***** My First C# App *****"); 
            Console.WriteLine($"Hello World!"); 
        } 
    } 
}

Note : C# is a case-sensitive programming language. Therefore, Main is not the same as main.

Be aware that all C# keywords are lowercase (e.g: public, lock, class, dynamic) while namespaces, types, and other member names begin (by convention) with an initial capital letter and the first letter of any embedded words is capitalized (e.g, Console.WriteLine, System.Windows.MessageBox).

The class that defines the Main() method is termed the application object. It's possible for a single executable application to have more than one application object, but then the compiler must know which Main() method should be used as the entry point. This can be done via the <StartupProject> element in the project file or via the StartupObject dropdown list box.

Static members are scoped to the class level (rather than the object level) and can thus be invoked without the need to first create a new class instance.

This Main() method has a single parameter, which happens to be an array of strings(string[] args). Finally, this Main() method has been set up with a void return value, meaning you don't explicitly define a return value using the return keyword before exiting the method scope.


Using Variations of the Main() Method

namespace Chapter_3 
{ 
    internal class SimpleCSharpApp 
    { 
        // static int Main(string[] args) { return 0; } 
        // static void Main() { } 
        // static int Main() { return 0; } 
        // static async Task Main() { await Task.Delay(1000); Console.WriteLine($"Hello World"); } 
        // static async Task<int> Main() { await Task.Delay(1000); return 0; } 
        // static async Task Main(string[] args) { await Task.Delay(1000); } 
        // static async Task<int> Main(string[] args) { await Task.Delay(1000); return 0; } 
        static void Main(string[] args) 
        { 
        } 
    } 
} 

Using Top-Level Statements (New 9.0)

While it is true that prior to C# 9.0, all C# .NET Core applications must have a Main() method, C# 9.0 introduced top-level statements, which eliminate the need for much of the ceremony around the C# application's entry point.

Console.WriteLine("dotnetguard.blog!");

There are some rules around using top-level statements:

  1. Only one file in the application can use top-level statements.
  2. When using top-level statements, the program cannot have a declared entry point.
  3. The top-level statements cannot be enclosed in a namespace.
  4. Top-level statements still access a string array of strings.
  5. Functions that would have been declared in the Program class become local functions for the top-level statements.
  6. The top-level statements compile to a class named Program, allowing for the addition of a partial Program class to hold regular methods.


Specifying an Application Error Code

When using top-level statements, if the executing code returns an integer, that is the return code. If nothing is explicitly returned, it still returns 0, as with explicitly using a Main() method.

On the Windows OS, an applications return value is stored within a system environment variable named %ERRORLEVEL%.

A vast majority of your C# applications will use "void" as the return value from Main(), which, as you recall, implicitly returns the error code of zero(0).

Processing Command-Line Arguments

  1. In the top-level statements:
for (int i = 0; i < args.Length; i++)
 {
     Console.WriteLine("Arg : {0}", args[i]);
 }
  1. System.Environment Type:
string[] theArgs = Environment.GetCommandLineArgs();
foreach (string arg in theArgs)
 {
     Console.WriteLine($"Arg {arg}");
 }


Additional Members of the System.Environment Class

This class allows you to obtain a number of details regarding the OS currently hosting your .NET 6 application using various static members.

Properties

CommandLineGets the command line for this process.
CurrentDirectoryGets or sets the fully qualified path of the current working directory.
CurrentManagedThreadIdGets a unique identifier for the current managed thread.
ExitCodeGets or sets the exit code for the application
HasShutdownStartedGets a value that indicates whether the current application domain is being unloaded or the CLR is shutting down.
Is64BitOperatingSystemGets a value that indicates whether the current OS is 64-bit OS system.
Is64BitProcessGets a value that indicates whether that current process is a 64-bit process.
MachineNameGets the NetBIOS name of this local computer.
NewLineGets the newline string define for this environment.
OSVersionGets the current platform identifier and version number.
ProcessorCountGets the number of processors available to the current process.
StackTraceGets the current stack trace information.
SystemDirectoryGets the fully qualified path of the system directory.
SystemPageSizeGets the number of bytes in the OS's memory page.
TickCountGets the number of milliseconds elapsed since the system started.
UserDomainNameGets the network domain name associated with the current user.
UserInteractiveGets a value indicating whether the current process is running in user interactive mode.
UserNameGets the username of the person who is associated with the current thread.
VersionGets a version consisting of the major, minor, build, and revision numbers of the CLR (Common Language Runtime)
WorkingSetGets the amount of physical memory mapped to the process context.

Methods

GetLogicalDrives()Retrieves the names of the logical drives in this computer. (public static string[] GetLogicalDrives(); )
ExpandEnvironmentVariables(string name)Replaces the name of each environment variable in the specified string with the string equivalent of the value of the variable, then returns the resulting string. Public static string ExpandEnvironmentVariables(string name);
GetEnvironmentVariables()Retrieves all environment variable names and their values from the current process. (public static System.Collections.Idictionary GetEnvironmentVariables();)
GetEnvironmentVariable(string variable)Retrieves the value of an environment variable from the current process. ( public static string? GetEnvironmentVariable(string variable); )
GetCommandLineArgs()public static string[] GetCommandLineArgs();
GetFolderPath(Environment.SpecialFolder folder)Gets the path to the specified system special folder.
SetEnvironmentVariable(string,string)Creates, modifies, or deletes an environment variable stored in the current process. (public static void SetEnvironmentVariable(string variable, string? value); )

Environment.SpecialFolder Fields:

ApplicationData
Desktop
Favorites
History
LocalApplicationData
MyComputer
MyDocuments
MyMusic
MyPictures
MyVideos
ProgramFiles
ProgramFilesx86
Startup
System
Systemx86
UserProfile
Windows



Using the System.Console Class

As its name implies, the Console class encapsulates input, output, and error-stream manipulations for console-based applications.

Note: Access to the Console class is now implicity provided by the global "using" statements provided .NET 6, negating the need to add in the "using System;" statement that was required in previous version of C# / .NET.


Properties

BackgroundColorGets or sets the background color of the console.
ForegrondColorGets or sets the foreground color of the console.
TitleGets or sets the title to display in the console title bar.
WindowHeightGets or sets the height of the console window area.
WindowWidthGets or sets the width of the console window area.

Methods

Beep()Plays the sound of a beep through the console speaker.
SetWindowSize(int,int)Sets the height and width of the console window to the specified values.
ResetColor()Sets the foreground and background console colors to their defaults.
Clear()Clears the established buffer and console display area.
SetCursorPosition(int,int)Sets the position of the cursor.

Performing Basic Input and Output (I/O) with Console Class

WriteLine() : Pumps a text string to the output with a carriage return (\n).

Write() : Pumps a text string to the output without a carriage return (\n).

ReadLine() vs Read() : ReadLine() allows you to receive information from the input stream up until the Enter key is pressed while Read() is used to capture a single character from the input stream.