© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
G. ByrneTarget C#https://doi.org/10.1007/978-1-4842-8619-7_1

1. .NET

Gerard Byrne1  
(1)
Belfast, Ireland
 

.NET: What Is It?

First, let us say that C# is a programming language, while .NET is the runtime that C# and other languages are built on. They are very different things, and when we program in C#, we need to be aware that we will intrinsically be using .NET. The version of .NET will be whatever version we download when we wish to start programming in C#. What .NET gives us as developers are libraries of code that save us from having to write our own code to perform particular tasks. For now, just think of a library as something where there are methods, small blocks of code, that perform a particular process.

A simple example would be a method in the library that allows us as developers to display text to a console window. This could be the WriteLine() method , and it is located in the Console class, which belongs inside a namespace called System. Our line of code could be
System.Console.WriteLine("------- Learn To Code With C# ------");
Or later as we become more familiar with the code, we will probably want to code it like this:
Console.WriteLine("------- Learn To Code With C# -------");

Either way, for now, we simply want to understand that if we add the text to be displayed between the open and close brackets () of the WriteLine() method, it will be displayed to the console. We do not have to write the code that makes it display in the console; we just accept that the C# language and .NET handle all this for us. So let us just think of .NET as giving us code in the form of methods that will save us lots of time when developing an application. Also, we should think method when we see the open and close brackets (). Other examples of methods that we will become very familiar with are Write() and ReadLine(), but there are many built-in methods from the libraries that we will use.

We should also be aware that we can program in languages other than C#, like F# and Visual Basic (VB), but .NET is underpinning all of the programming languages supported by it. The libraries in .NET are shared between all the languages, thereby avoiding duplication of libraries and their contained methods. This makes sense as “on the surface” the WriteLine() method for displaying to the console should be the same no matter what .NET-supported language we program in. We do not need to concern ourselves that the different languages “under the hood” use different compilers.

As well as supplying developers with invaluable functionality through its methods and constructs, .NET includes a runtime environment for applications. This runtime environment is called the Common Language Runtime (CLR) , and it is the “engine” that produces the magic to allow us as developers to write code in any of the .NET-supported languages, and it will run on any device that has .NET installed. It is a “virtual machine” that lets .NET exist on a device and then it can manage .NET applications running within.

Finally, think of .NET this way: it is the environment and C# lives within it, as do other languages. Yes, it is like us: the earth is the environment, and we live within it alongside others. The environment supplies us with many useful facilities like sunshine, air, and rain, and we use these in our life as we wish to do. Our environment offers us many facilities, some we use and some we don't use. Well, the same goes when we program in C# and use .NET; we will use some of the facilities, and we will not use others.

.NET Core: What Is It?

We have just read about .NET being the runtime that C# and other languages are built on, but there is a history to .NET that can confuse us, so we will look at this history in order to help us better understand how we have reached the stage where we now just say .NET, as we have done in the preceding introductory paragraphs.

The evolution and progression of .NET implementations and their names has led to confusion around the .NET topic. The history has been as follows:
  • .NET Framework was launched as .NET Framework 1 in 2002 and went on to have versions up to the last version of .NET Framework 4.8. It allowed only for the development of Windows applications.

  • .NET Core was introduced in 2016 in an attempt to include cross-platform support, for example, for Linux and MacOS. .NET Core went from version 1 to the last version, 3.

  • .NET was introduced as .NET 5 in 2020 with Microsoft dropping the name Core and naming it with 5 rather than 4, in an attempt to differentiate from the .NET Framework, which was version 4. .NET 6 then followed in 2021 and in 2022 .NET 7.

So we can see that .NET Core aimed, for the first time, to give developers the facilities to develop for non-Windows devices such as mobile phones and Linux and Mac operating systems, using a standard set of libraries, which we mentioned earlier as being methods that give us functionality without having to write the code. It was not created to allow for development of desktop applications .

.NET Core was aimed at making .NET more modern, faster, and more scalable, and we could say that the philosophy behind it was to allow developers to build code once and that would run on any platform. Nowadays, we will hear a lot of talk about micro-services, small units of code living independently in the ecosystem, but able to communicate with each other when required, and .NET Core offers developers the opportunity to build micro-services.

We can therefore see that Microsoft started by offering us the .NET Framework, which ran only on Windows, and then evolved to offering us .NET Core, which allowed for cross-platform development. And now we have .NET, which runs on any platform and is the future with new releases every November. .NET is therefore a replacement for the other two.

As we are interested in developing our C# programming skills, we do not need to concern ourselves with the underlying runtime.

C# Language Versioning

There are many versions of the C# programming language , and this can cause confusion when we wish to write code and are required to choose a language level. To make the situation more confusing, there are many versions of .NET, which the C# language must work with. To help us and take the “pain” out of making the C# language version choice, the C# compiler will make the decision as to which version of C# to use, based on the .NET version we have chosen to develop our application in. This is a feature aimed at ensuring that we, as developers, are using the latest C# version for the chosen .NET version. When we use the Visual Studio Integrated Development Environment, it will use the .NET version installed on our computers, and, consequently, we will be availing of the latest version of the C# language that can be used with this .NET version. By using the highest C# version, we get the latest language features, but we still have the choice to use a different version if this is required. Caution is required when manually choosing the language level as we may be trying to use language features not supported by the selected .NET version.

By looking on the Microsoft site docs.​microsoft.​com, we will get the latest information about versions of the .NET framework and the C# language. We can also download versions of .NET from the Microsoft site dotnet.​microsoft.​com. So information from the site and relevant to our discussion and learning is as follows:
  • C# 10 is only supported on .NET 6 and newer versions.

  • C# 9 is only supported on .NET 5 and newer versions.

  • C# 8 is only supported on .NET Core version 3.x and newer versions.

  • C# 7.3 is the latest supported version for the .NET Framework.

Once we start to write our code in the Visual Studio Integrated Development Environment, we will create a C# project, which will generate a .csproj file, and it is within this file that we are able to set the language level. Visual Studio does not supply us with a user interface (UI) to make changes to the .csproj file, but we can select the file and edit its contents to ensure that the language version is set. An example of the code contained in the .csproj is shown in Listing 1-1.
<PropertyGroup>
   <LangVersion>10</LangVersion>
</PropertyGroup>
Listing 1-1

Language level within the .csproj file

A timeline titled dot NET evolution starts in 2002 with the dot NET framework, versions 1 to 4. It then moves in 2016 to dot NET core, versions 1 to 3, and to dot NET in 2020, with versions 5 and so on.

Figure 1-1

.NET evolution .NET Framework to .NET Core to .NET

.NET and C# Compilation Process

Part of the .NET framework is based on giving developers the tools they require to convert their C# code into a format that can be understood by the operating system that will run the application. As developers we follow a process to make the code we have written in our chosen .NET programming language into machine-readable code. Here are the steps of the compile process :
  • Write the code in C# or another .NET programming language.

  • Compile the code using the compiler, which checks the code for errors such as in syntax. We can then make the required changes.

  • The compiler produces Common Intermediate Language (CIL) files and these files for C# would be similar if we had written our code in another .NET programming language. That is the “beauty” of .NET write in any language and it will compile to the same thing.

  • The Common Language Runtime (CLR) takes control of the process, and we previously read that the Common Language Runtime is

the “engine” that produces the magic to allow us as developers to write code in any of the .NET-supported languages, and it will run on any device that has .NET installed.

  • Once the intermediate language has been generated, the Common Language Runtime process uses the Just-In-Time (JIT) compiler to create the code that the specific operating system running the application requires. This means our development code has been compiled twice, first to the Common Intermediate Language and second to machine-specific code.

For developers what is nice about .NET is that the Common Language Runtime is common, which means that it is the same runtime “engine” for all .NET programming languages, for example, C# and VB.NET. Another great thing about programming in C# and using the .NET framework is that as developers we do not have to concern ourselves with the inner workings of compiling, intermediate language, Just-In-Time compiling, and machine code. It is all handled for us. We write the C# code and get it free of compilation errors, and .NET takes over. We do not even have to concern ourselves about different hardware and processors. As long as the .NET framework is available on the device running the application, everything is handled. Figure 1-2 offers a way to look at the compile process.

A flow diagram of the compilation process has 5 steps. It starts with the C hash code, followed by the C hash compiler, C I L, J I T, and ends with the machine or native code.

Figure 1-2

The compile process

Compile Time and Runtime

As we learn about programming, we hear the terms compile time and runtime, so it is important to understand the difference and their role in the development process. Figure 1-3 offers a way to look at which parts of the development process are compile time and which are runtime.

A compile time and runtime diagram. C hash code, C hash compiler, and C I L are part of the compile time, while J I T and machine code are parts of the runtime.

Figure 1-3

Compile time and runtime

When we choose to compile our code, the compiler takes the code and does some processing. Often the compile process finds errors in the code, for example, typographical errors, and we will be prompted to make changes to fix these compilation errors. So we are at compile time when we have written some code, and we choose to compile it in one of several different ways, for example, choosing Run from a menu, pressing a specified function key like F5, or typing a command at the command line. At compile time our code is still C#, but when the compiler finishes its processing, it will produce files in the form of an executable file, an .exe, or a dynamic link library, a .dll. These files are still not capable of being understood by the computer the code is to run on as the computer processor only understands machine code.

Now the second stage of the process is where we meet the runtime. When we want the application to run on a computer, this is the runtime, and it is the Common Language Runtime that handles this phase. At runtime the .exe or .dll files are converted to machine code capable of being read by the specific computer processor that the application is being run on. The conversion to machine code at runtime is handled by a specific part of the Common Language Runtime called the Just-In-Time compiler. Even though the compilation errors have been fixed and the code compiles, there is no guarantee that the code will run. If the code does not run at runtime, there will be runtime errors , and these are much more serious than compilation errors and present themselves where the end user can see them. This will not be a “happy” experience for the end user and should never happen, but things like this do happen. It is a rather unfortunate part of software development. A runtime error could occur because a file is not found or the memory is fully allocated, and often the consequence of a runtime error is the termination of the application.

Framework and Library

While learning to program, we will hear the terms framework and library being used widely, but it is easy to get confused about what each does and why they are different.

Library

At the start of this chapter, we read the following:

For now, just think of a library as something where there are methods, small blocks of code, that perform a particular process.

This is a simple explanation, but we can go further and say that it is a collection of routines, blocks of code, that can be reused and have been thoroughly tried and tested. FinMath is a numerical library for the .NET platform that offers developers classes and methods for mathematical, scientific, and financial applications. As developers we use the libraries by calling the methods of the library whenever we require them in our code. We control the use of the libraries, and we should make use of libraries rather than writing our own code to perform the same functionality as library functions. All this fits in with the important concept of reusing software functionality when we can.

Think of a library in the context of building our own motor vehicle. We will choose the type of engine, the body shape, the number of seats, the wheel types, the color we will spray on the bodywork, etc. We are in control of what to include and what to leave out.

Framework

At the start of this chapter, we read the following:

So let us just think of .NET as giving us code in the form of methods that will save us lots of time when developing an application.

This is also a simple explanation, but we can be more accurate by saying that the framework controls the calling of libraries rather than us as developers calling the libraries. Think of a framework like buying a limited-edition motor vehicle where have no choice in terms of the configuration. The vehicle is designed and built so we cannot customize it and we cannot pick the type of engine, the body shape, the number of seats, the wheel types, the color of the bodywork, etc. We are not in control of what to include. The special edition is a “constant,” and all the vehicles are identical.

Throughout our lifetime as developers, we will use many frameworks and libraries, and they both help us through their tested and reusable code. The essential difference is that as developers we call the code from the library, but the frameworks will call our code, as in Figure 1-4. Put in technical speak, we say it is all about inversion of control .

A diagram of the difference between a library and a framework. Developers call the code from the library, while the framework calls the developer's code.

Figure 1-4

Framework vs. library

In terms of real-world business, we can see that there are many food franchise companies and they offer people the opportunity to invest their own money and become a franchisee. As a franchisee you follow the framework set up by the franchise company. You use their logo, their paper cups, their coffee, their burgers, or whatever. A franchisee cannot pick and choose and say, “I'll use the paper cups, but I want to sell different coffee or different burgers or use different fillings.” The franchise company is like our coding framework, as shown in Figure 1-5.

An illustration describes how the franchise company dictates to the franchisee. This means that the franchisee follows the framework of the franchise company.

Figure 1-5

Framework in business

On the other hand, a public house might be “tied” to a particular beer company and as such they can only sell the beer from that company. However, they can sell what soft drinks they want, whatever food they like, etc. This is like a library in that the public house owner has selected this beer company but can use other non-libraries for their soft drinks, meaning that they could choose a different supplier every day or choose a different soft drink every day, as shown in Figure 1-6.

A block diagram illustrates how a public house dictates to the suppliers. This means the public house is tied to a certain supplier for a specific product.

Figure 1-6

Library in business

Managed and Unmanaged Code

Two terms we will hear when reading about C# and .NET are managed code and unmanaged code , and while starting to learn to program in C# it is not essential to fully understand the terms, it is worth having at a conceptual overview.

Managed code is code that is managed by the Common Language Runtime, which we read about earlier where we stated that

At runtime the .exe or .dll files are converted to machine code capable of being read by the specific computer processor that the application is being run on.

The Common Language Runtime also takes care of wider issues such as memory allocation and garbage collection. Therefore, we do not need to concern ourselves with these things; we just concentrate on coding the C#.

Unmanaged code is code that must be managed by us as developers. We take over the role of the Common Language Runtime, and we need to manage the wider issues such as memory allocation and garbage collection. This adds many additional tasks for us as developers and this is never an ideal situation to be in. Unmanaged code will be code built and compiled outside of the .NET environment and will be in machine-readable form, unlike managed code which will be in intermediate language. Unmanaged code is therefore read directly by the hardware operating system it is running on. The preference will always be that we are using managed code, and that is what we get when using C# and the .NET framework.

Chapter Summary

In this chapter we have learned so much about the .NET framework, but it has been theoretical. However, it is theory we need to know before we start coding. We may not have fully comprehended all the theory, but be assured that many of the concepts will become crystallized as we continue our reading and when we code our C# applications.

There should be many key takeaways from this chapter, but we should clearly understand that C# is a programming language, while .NET is the framework that the C# and other languages are built on. We should also understand the difference between compile time and runtime. We learned that after compiling, our code files in the form of an executable file, an .exe, or a dynamic link library, a .dll, are produced. At runtime the .exe or .dll files are converted to machine code capable of being read by the specific computer processor that the application is being run on. Very importantly, we also learned that a library is a collection of routines, blocks of code, that have been compiled, can be reused, and have been thoroughly tried and tested. And we will use them in coding our applications.

We have started reading this book with the aim of increasing our knowledge and understanding of C#. We are at the start of the learning journey and the final target can be thought of as being at the center of a set of concentric circles. As we progress through the chapters of this book, our knowledge, understanding, and ability to program in C# will gradually increase, while the amount we have to learn will decrease. The outer circles of the concentric circles will disappear as we move closer to the circle at the center, our target. Having completed this chapter, we are at the outer circle, but we are moving closer to our target.

An illustration of concentric circles in which the circles near the center are considered the targets. A text below the illustration reads, our target is getting closer.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.30.211