Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
C# 13 and .NET 9 – Modern Cross-Platform Development Fundamentals

You're reading from   C# 13 and .NET 9 – Modern Cross-Platform Development Fundamentals Start building websites and services with ASP.NET Core 9, Blazor, and EF Core 9

Arrow left icon
Product type Paperback
Published in Nov 2024
Publisher Packt
ISBN-13 9781835881224
Length 828 pages
Edition 9th Edition
Languages
Arrow right icon
Toc

Table of Contents (18) Chapters Close

Preface 1. Hello, C#! Welcome, .NET! 2. Speaking C# FREE CHAPTER 3. Controlling Flow, Converting Types, and Handling Exceptions 4. Writing, Debugging, and Testing Functions 5. Building Your Own Types with Object-Oriented Programming 6. Implementing Interfaces and Inheriting Classes 7. Packaging and Distributing .NET Types 8. Working with Common .NET Types 9. Working with Files, Streams, and Serialization 10. Working with Data Using Entity Framework Core 11. Querying and Manipulating Data Using LINQ 12. Introducing Modern Web Development Using .NET 13. Building Websites Using ASP.NET Core 14. Building Interactive Web Components Using Blazor 15. Building and Consuming Web Services 16. Epilogue 17. Index

Building console apps using Visual Studio

The goal of this section is to showcase how to build a console app using Visual Studio.

If you do not have a Windows computer or want to use VS Code, then you can skip this section, since the code will be the same; just the tooling experience is different. However, I recommend that you review this section because it does explain some of the code and how top-level programs work, and that information applies to all code editors.

This section is also available in the GitHub repository (so it can be updated after publishing if needed) at the following link:

https://github.com/markjprice/cs13net9/blob/main/docs/code-editors/vs.md

If you want to see similar instructions for using Rider, they are available in the GitHub repository at the following link:

https://github.com/markjprice/cs13net9/blob/main/docs/code-editors/rider.md

Writing code using Visual Studio

Let’s get started writing code:

  1. Start Visual Studio.
  2. In the Create a new project dialog, select the C# language to filter the project templates, enter console in the Search for templates box, and then select Console App.

Make sure that you have chosen the cross-platform project template, not the one for .NET Framework, which is Windows-only, and the C# project template rather than another language, such as Visual Basic or TypeScript.

  1. Click Next.
  2. In the Configure your new project dialog, enter HelloCS for the project name, C:\cs13net9 for the location, and Chapter01 for the solution name.

Screenshots of Visual Studio when creating new projects can be found in the GitHub repository at the following link: https://github.com/markjprice/cs13net9/blob/main/docs/ch01-project-options.md.

  1. Click Next.
  2. In the Additional information dialog, in the Framework drop-down list, note that your .NET SDK choices indicate if that version is Standard Term Support, Long Term Support, Preview, or Out of support, and then select .NET 9.0 (Standard Term Support).

You can install as many .NET SDK versions as you like. If you are missing a .NET SDK version, then you can install it from the following link: https://dotnet.microsoft.com/en-us/download/dotnet.

  1. Leave the checkbox labeled Do not use top-level statements clear. (Later in this chapter, you will create a console app that selects this option, so you will see the difference.)
  2. Leave the checkbox labeled Enable native AOT publish clear. You will learn what this option does in Chapter 7, Packaging and Distributing .NET Types.
  3. Click Create.
  4. If you cannot see Solution Explorer, then navigate to View | Solution Explorer.
  5. If code is not shown, then in Solution Explorer, double-click the file named Program.cs to open it, and note that Solution Explorer shows the HelloCS project, as shown in Figure 1.4:

Figure 1.4: Editing Program.cs in Visual Studio

  1. In Program.cs, note that the code consists of only a comment and a single statement, as shown in the following code:
    // See https://aka.ms/new-console-template for more information
    Console.WriteLine("Hello, World!");
    

    This template uses the top-level program feature introduced in C# 9, which I will explain later in this chapter. As the comment in the code says, you can read more about this template at the following link: https://aka.ms/new-console-template.

  1. In Program.cs, modify line 2 so that the text that is being written to the console says Hello, C#!.

    All code examples and commands that you must review or type are shown in plain text, so you will never have to read code or commands from a screenshot, like in Figure 1.4, which might be too small or too faint in print.

Compiling and running code using Visual Studio

The next task is to compile and run the code:

  1. In Visual Studio, navigate to Debug | Start Without Debugging.

Good Practice: When you start a project in Visual Studio, you can choose whether to attach a debugger or not. If you do not need to debug, then it is better not to attach one because attaching a debugger requires more resources and slows everything down. Attaching a debugger also limits you to only starting one project. If you want to run more than one project, each with a debugger attached, then you must start multiple instances of Visual Studio. In the toolbar, click the green outline triangle button (to the right of HelloCS in the top bar shown in Figure 1.5) to start without debugging, instead of the green solid triangle button (to the left of HelloCS in the top bar shown in Figure 1.5), unless you need to debug.

  1. The output in the console window will show the result of running your application, as shown in Figure 1.5:

Figure 1.5: Running the console app on Windows

  1. Press any key to close the console app window and return to Visual Studio.
  2. Optionally, close the Properties pane to make more vertical space for Solution Explorer.
  3. Double-click the HelloCS project, and note that the HelloCS.csproj project file shows that this project has its target framework set to net9.0, as shown in Figure 1.6.
  4. In the Solution Explorer toolbar, toggle on the Show All Files button, and note that the compiler-generated bin and obj folders are visible, as shown in Figure 1.6:

Figure 1.6: Showing the compiler-generated folders and files

Understanding the compiler-generated folders and files

Two compiler-generated folders were created, named obj and bin, as described in the following list:

  • The obj folder contains one compiled object file for each source code file. These objects haven’t been linked together into a final executable yet.
  • The bin folder contains the binary executable for the application or class library. We will look at this in more detail in Chapter 7, Packaging and Distributing .NET Types.

You do not need to look inside these folders or understand their files yet (but feel free to browse around if you are curious).

Just be aware that the compiler needs to create temporary folders and files to do its work. You could delete these folders and their files, and they will be automatically recreated the next time you “build” or run the project. Developers often delete these temporary folders and files to “clean” a project. Visual Studio even has a command on the Build menu named Clean Solution that deletes some of these temporary files for you. The equivalent command with the CLI is dotnet clean.

Understanding top-level programs

If you have seen older .NET projects before, then you might have expected more code, even just to output a simple message. This project has minimal statements because some of the required code is written for you by the compiler when you target .NET 6 or later.

If you had created the project with .NET SDK 5 or earlier, or if you had selected the checkbox labeled Do not use top-level statements, then the Program.cs file would have more statements, as shown in the following code:

using System;
namespace HelloCS
{
  class Program
  {
    static void Main(string[] args)
    {
      Console.WriteLine("Hello, World!");
    }
  }
}

During compilation with .NET SDK 6 or later, all the boilerplate code to define the Program class and its Main method is generated and wrapped around the statements you write.

This uses a feature introduced in .NET 5 called top-level programs, but it was not until .NET 6 that Microsoft updated the project template for console apps to use top-level statements by default. Then, in .NET 7 and later, Microsoft added options to use the older style if you prefer:

  • If you are using Visual Studio, select the checkbox labeled Do not use top-level statements.
  • If you are using the dotnet CLI at the command prompt, add a switch:
    dotnet new console --use-program-main
    

Warning! One functional difference is that the auto-generated code does not define a namespace, so the Program class is implicitly defined in an empty namespace with no name, instead of a namespace that matches the name of the project.

Requirements for top-level programs

Key points to remember about top-level programs include the following:

  • There can be only one file like the file you use for top-level program code in a project.
  • Any using statements must be at the top of the file.
  • If you declare any classes or other types, they must be at the bottom of the file.
  • Although you should name the entry-point method Main if you explicitly define it, the method is named <Main>$ when created by the compiler.

Implicitly imported namespaces

The using System; statement at the top of the file imports the System namespace. This enables the Console.WriteLine statement to work. But why do we not have to import it in our project?

The trick is that we still need to import the System namespace, but it is now done for us using a combination of features introduced in C# 10 and .NET 6. Let’s see how:

  1. In Solution Explorer, expand the obj, Debug, and net9.0 folders, and open the file named HelloCS.GlobalUsings.g.cs.
  2. Note that this file is automatically created by the compiler for projects that target .NET 6 or later and uses a feature introduced in C# 10, called global namespace imports, which imports some commonly used namespaces like System for use in all code files, as shown in the following code:
    // <autogenerated />
    global using global::System;
    global using global::System.Collections.Generic;
    global using global::System.IO;
    global using global::System.Linq;
    global using global::System.Net.Http;
    global using global::System.Threading;
    global using global::System.Threading.Tasks;
    
  3. In Solution Explorer, click the Show All Files button to hide the bin and obj folders.

I will explain more about the implicit imports feature in the next chapter. For now, just note that a significant change that happened between .NET 5 and .NET 6 is that many of the project templates, like the one for console apps, use new SDK and language features to hide what is really happening.

Revealing the hidden code by throwing an exception

Now let’s discover how the hidden code has been written:

  1. In Program.cs, after the statement that outputs the message, add a statement to throw a new exception, as shown in the following code:
    throw new Exception();
    
  2. In Visual Studio, navigate to Debug | Start Without Debugging. (Do not start the project with debugging, or the exception will be caught by the debugger!)
  3. The output in the console window will show the result of running your application, including that a hidden Program class was defined by the compiler, with a method named <Main>$ that has a parameter named args to pass in arguments, as shown in Figure 1.7 and the following output:
    Hello, C#!
    Unhandled exception. System.Exception: Exception of type 'System.Exception' was thrown.
       at Program.<Main>$(String[] args) in C:\cs13net9\Chapter01\HelloCS\Program.cs:line 3
    

Figure 1.7: Throwing an exception to reveal the hidden Program.<Main>$ method

  1. Press any key to close the console app window and return to Visual Studio.

Revealing the namespace for the Program class

Now, let’s discover what namespace the Program class has been defined within:

  1. In Program.cs, before the statement that throws an exception, add statements to get the name of the namespace of the Program class, and then write it to the console, as shown in the following code:
    string name = typeof(Program).Namespace ?? "<null>";
    Console.WriteLine($"Namespace: {name}");
    

?? is the null-coalescing operator. The first statement means, “If the namespace of Program is null, then return <null>; otherwise, return the name.” You will see more explanations of these keywords and operators throughout the book. For now, just enter the code and run it to see what it does.

Good Practice: Code editors have a feature named code snippets. These allow you to insert pieces of code that you commonly use, by typing a shortcut and pressing Tab twice. For example, in Visual Studio, to enter Console.WriteLine() and leave the cursor in the middle of the parentheses ready for you to type what you want to output, type cw, and then press Tab, Tab. Read the documentation for your code editor to learn how to insert code snippets using shortcuts.

  1. In Visual Studio, navigate to Debug | Start Without Debugging.
  2. The output in the console window will show the result of running your application, including that the hidden Program class was defined without a namespace, as shown in the following output:
    Namespace: <null>
    
  3. Press any key to close the console app window and return to Visual Studio.

Adding a second project using Visual Studio

Let’s add a second project to our solution to explore how to work with multiple projects:

  1. In Visual Studio, navigate to File | Add | New Project….

    Warning! The above step adds a new project to the existing solution. Do NOT navigate to File | New | Project…, which instead is meant to be used to create a new project and solution (although the dialog box has a dropdown to choose to add to an existing solution too).

  1. In the Add a new project dialog, in Recent project templates, select Console App [C#], and then click Next.
  2. In the Configure your new project dialog, for Project name, enter AboutMyEnvironment, leave the location as C:\cs13net9\Chapter01, and then click Next.
  3. In the Additional information dialog, select .NET 9.0 (Standard Term Support) and select the Do not use top-level statements checkbox.

Warning! Make sure you have selected the Do not use top-level statements checkbox so that we get to see the older style of Program.cs.

  1. Click Create.
  2. In the AboutMyEnvironment project, in Program.cs, note the statements to define a namespace that matches the project name, an internal class named Program, and a static method named Main with a parameter named args that returns nothing (void), as shown in the following code:
    namespace AboutMyEnvironment
    {
      internal class Program
      {
        static void Main(string[] args)
        {
          Console.WriteLine("Hello, World!");
        }
      }
    }
    
  3. In Program.cs, in the Main method, replace the existing Console.WriteLine statement with statements to output the current directory, the version of the operating system, and the namespace of the Program class, as shown in the following code:
    Console.WriteLine(Environment.CurrentDirectory);
    Console.WriteLine(Environment.OSVersion.VersionString);
    Console.WriteLine("Namespace: {0}",
      typeof(Program).Namespace ?? "<null>");
    
  4. In Solution Explorer, right-click the Chapter01 solution, and then select Configure Startup Projects….
  5. In the Solution ‘Chapter01’ Property Pages dialog box, set Startup Project to Current selection, and then click OK.
  6. In Solution Explorer, click the AboutMyEnvironment project (or any file or folder within it), and note that Visual Studio indicates that AboutMyEnvironment is now the startup project by making the project name bold.

Good Practice: I recommend this way of setting the startup project because it then makes it very easy to switch startup projects by simply clicking a project (or any file in a project) to make it the startup project. Although you can right-click a project and set it as a startup project, if you then want to run a different project, you must manually change it again. Simply clicking anywhere in the project is easier. In most chapters, you will only need to run one project at a time. In Chapter 15, Building and Consuming Web Services, I will show you how to configure multiple startup projects.

  1. Navigate to Debug | Start Without Debugging to run the AboutMyEnvironment project, and note the result, as shown in the following output and Figure 1.8:
    C:\cs13net9\Chapter01\AboutMyEnvironment\bin\Debug\net9.0
    Microsoft Windows NT 10.0.26100.0
    Namespace: AboutMyEnvironment
    

Figure 1.8: Running a console app in a Visual Studio solution with two projects

Windows 11 is just branding. Its official name is Windows NT, and its major version number is still 10! But its patch version is 22000 or higher.

  1. Press any key to close the console app window and return to Visual Studio.

    When Visual Studio runs a console app, it executes it from the <projectname>\bin\Debug\net9.0 folder. It will be important to remember this when we work with the filesystem in later chapters. When using VS Code, or more accurately, the dotnet CLI, it has different behavior, as you are about to see.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image