Hands-On Object-Oriented Programming with C#

3.5 (2 reviews total)
By Raihan Taher
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Overview of C# as a Language

About this book

Object-oriented programming (OOP) is a programming paradigm organized around objects rather than actions, and data rather than logic. With the latest release of C#, you can look forward to new additions that improve object-oriented programming.

This book will get you up to speed with OOP in C# in an engaging and interactive way. The book starts off by introducing you to C# language essentials and explaining OOP concepts through simple programs. You will then go on to learn how to use classes, interfacesm and properties to write pure OOP code in your applications. You will broaden your understanding of OOP further as you delve into some of the advanced features of the language, such as using events, delegates, and generics. Next, you will learn the secrets of writing good code by following design patterns and design principles. You'll also understand problem statements with their solutions and learn how to work with databases with the help of ADO.NET. Further on, you'll discover a chapter dedicated to the Git version control system. As you approach the conclusion, you'll be able to work through OOP-specific interview questions and understand how to tackle them.

By the end of this book, you will have a good understanding of OOP with C# and be able to take your skills to the next level.

Publication date:
February 2019
Publisher
Packt
Pages
288
ISBN
9781788296229

 

Overview of C# as a Language

With the introduction of modern-day programming practices, it is evident that developers are looking for more advanced constructs to help them to deliver the best software in the most effective way. Languages that evolve on top of frameworks are built to enhance the capabilities of the developers in a way that allows them to quickly build their code with less complexity so that the code is maintainable, yet readable.

There are many high-level object, oriented programming languages available on the market, but among them I would say one of the most promising is C#. The C# language is not new in the programming world and has existed for over a decade, but with the dynamic progress of the language itself creating so many newer constructs, it has already left some of the most widely accepted language competition behind. C# is an object-oriented, type-safe, general-purpose language that is built on top of the .NET framework that was developed by Microsoft and approved by the European Computer Manufacturers Association (ECMA) and the International Standards Organization (ISO). It is built to run on the Common Language Infrastructure and can interact with any other languages that are built based on the same architecture. Inspired by C++, the language is rich in delivering the best of breed applications without handling too many complexities in code.

In this chapter, we will cover the following topics:

  • Evolution of C#
  • Architecture of C#
  • Fundamentals and syntax of the C# language
  • Visual Studio as an editor
  • Writing your first program in Visual Studio
 

Evolution of C#

C# has been one of the most dynamic languages in recent times. This language is open source and mostly driven by a group of software engineers, who recently came up with lots of major changes to enhance the language and provide features to handle the complexities in the languages that exist. Some of the major enhancements that have been put forward for the language include Generics, LINQ, Dynamics, and the async/await pattern:

In the preceding diagram, we can see how the language has evolved from its inception with managed code in C# 1.0, to async programming constructs that were introduced in C# 5.0, to modern-day C# 8. Before going further, let's look at some of the highlights of C# in its different stages of evolution.

Managed code

The phrase managed code came into being after Microsoft declared the .NET framework. Any code running in a managed environment is handled by Common Language Runtime (CLR), which keeps

Generics

Generics is a concept that was introduced with C# 2.0 and allows template type definition and type parameters. Generics allow the programmer to define types with open-ended type parameters that dramatically changed the way that programmers write code. The type-safety with dynamic typed generic templates improves readability, reusability, and code performance.

LINQ

The third installment of the C# language introduced Language Integrated Query (LINQ), a new construct of queries that can be run over object structures. LINQ is very new to the programming world and gives us a glimpse of functional programming on top of object-oriented general programming structure. LINQ also introduced a bunch of new interfaces in the form of the IQueryable interface, which introduced a number of libraries that can interact with the external world using LINQ. LINQ was boosted with the introduction of Lambda expressions and expression trees.

Dynamics

The fourth instalment also provides a completely new construct. It introduces the dynamic language structure. The dynamic programming capability helps the developer to defer the programming calls to runtime. There is a specific syntactic sugar that was introduced in the language that compiles the dynamic code on the same runtime. The version also puts forward a number of new interfaces and classes that enhance its language capabilities.

Async/await

With any language, threading or asynchronous programming is a pain. When dealing with asynchrony, the programmers have to come across many complexities that reduce the readability and maintainability of the code. With the async/await feature in the C# language, programming in an asynchronous way is as simple as synchronous programming. The programming has been simplified, with all of the complexities handled by the compiler and the framework internally.

Compiler as a service

Microsoft has been working on how some parts of the source code of the compiler can be opened up to the world. Consequently, as a programmer, you are capable of querying the compiler on some of its internal work principles. C# 6.0 introduced a number of libraries that enable the developer to get an insight into the compiler, the binder, the syntax tree of the program, and so on. Although the features were developed for a long time as the Roslyn project, Microsoft have finally released it to the external world.

Exception filters

C# 6.0 is adorned with a lot of smaller features. Some of the features give the developers an opportunity to implement complex logic with simple code, while some of them enhance the overall capabilities of the language. Exception filters are newly introduced with this version and give a program the capability to filter out certain exception types. The exception filters, being a CLR construct, have been hidden in the language throughout its lifetime, but were finally introduced with C# 6.0.

C# 8 and beyond

With C# being the most dynamic language in the market, it is constantly improving. With the newer features, such as nullable reference types, async streams, ranges and indices, interface members, and many other features that came with the latest version of C#, they have enhanced the basic features and helped programmers to take advantage of these new constructs, hence making their lives easier.

Note that, during the language's evolution, the .NET framework was also made open source. You can find the source code of the .NET framework at the following link: https://referencesource.microsoft.com/.

 

Architecture of .NET

Even though it is a decade old, the .NET framework is still well-built and makes sure to make it tiered, moduler, and hierarchical. Each tier provides specific functionalities to the user—some in terms of security and some in terms of language capabilities. The tiers produce a layer of abstraction to the end users and hide most of the complexities of the native operating system as much as possible. The .NET framework is partitioned into modules, with each of them having their own distinct responsibilities. The higher tiers request specific capabilities from the lower tiers and hence it is hierarchical.

Let's look at a diagram of the .NET architecture:

The preceding diagram depicts how the .NET framework architecture is laid out. On its lowest level, it is the operating system that interacts with the kernel APIs that are present in the operating system. The Common Language Infrastructure connects with the CLR, which provides services that monitor each code execution and managed memory, handles exceptions, and ensures that the application behaves as intended. Another important goal of the infrastructure is language inter-operability. The common language runtime is yet again abstracted with the .NET class libraries. This layer holds the binaries that the language is built on, and all of the compilers built on top of the libraries provide the same compiled code so that the CLR can understand the code and interact easily with one another.

Before going further, let's quickly look at some of the key aspects on which languages are built on the .NET framework.

Common Language Runtime

The CLR provides an interfacing between the underlying unmanaged infrastructure with the managed environment. This provides all of the basic functionalities of the managed environment in the form of garbage collection, security, and interoperability. The CLR is formed with the just-in-time compiler, which compiles the assembly code that's produced with the specific compilers to the native calls. CLR is the most important portion of the .NET architecture.

Common Type System

As there is a layer of abstraction between the language and the framework, it is evident that each of the language literals are mapped to specific CLR types. For instance, the integer of VB.NET is the same as the int of C#, as both of them point to the same type, System.Int32. It is always preferred to use language types since the compiler takes care of the mapping of types. The CTS system is built as a hierarchy of types with System.Object at its apex. The Common Type System (CTS) is divided into two kinds, one of which is value types, which are primitives that are derived from System.ValueTypes, while anything other than that is a reference type. The value types are treated differently to the reference types. This is because while allocation of memory value types are created on a thread stack during execution, reference types are always created on the heap.

.NET framework class libraries

The framework class library lies in-between the language and the CLR, and therefore any type that's present in the framework is exposed to the language you code. The .NET framework is formed with a good number of classes and structures, exposing never-ending functionalities that you, as a programmer, can benefit from. The class libraries are stored in the form of binaries that can be referenced directly from your program code.

Just-in-time compiler

.NET languages are compiled twice. During the first form of compilation, the high-level language is converted into a Microsoft Intermediate Language (MSIL), which can be understood by the CLR, while the MSIL is again compiled during runtime when the program is executed. The JIT works inside the program runtime and periodically compiles the code that is expected to be required during execution.

 

Fundamentals and syntax of C# language

Being a high-level language, C# is adorned with a lot of newer and updated syntax, which helps the programmer to write code efficiently. As we mentioned earlier, the type system that's supported by the language is divided into two types:

  • Value types
  • Reference types

The value types are generally primitive types that are stored in the stack during local execution for faster allocation and deallocation of memory. The value types are mostly used during the development of code and, consequently, this forms the major spectrum of the code altogether.

Data types

The basic data types of C# are divided into the following categories:

  • Boolean type: bool
  • Character type: char
  • Integer types: sbyte, byte, short, ushort, int, uint, long, and ulong
  • Floating-point types: float and double
  • Decimal precision: decimal
  • String: string
  • Object type: object

These are primitive data types. These data types are embedded in the C# programming language.

Nullable types

The primitive types or value types are not nullable in C#. Consequently, there is always a requirement for the developer to make the type nullable, as a developer might need to identify whether the value is provided explicitly or not. The newest version of .NET provides nullable types:

Nullable<int> a = null;
int? b = a; //same as above

Both lines in the preceding example define the nullable variable, while the second line is just a shortcut of the first declaration. When the value is null, the HasValue property will return false. This will ensure that you can detect whether the variable is explicitly specified as a value or not.

Literals

Literals are also an important part of any program. C# language gives the developer different kinds of options that allow the programmer to specify literals in code. Let's take a look at the different types of literals that are supported.

Boolean

Boolean literals are defined in the form of true or false. No other values except true and false can be assigned in the Boolean type:

bool result = true;

The default value of a Boolean type is false.

Integer

An integer is a number that can have a plus (+) or minus (-) sign as a prefix, but this is optional. If no sign is given, it is considered as positive. You can define numeric literals in int, long, or hexadecimal form:

int numberInDec = -16;
int numberInHex = -0x10;
long numberinLong = 200L;

You can see that the first literal, -16, is a literal that's been specified in an integer variable, while the same value is assigned to an integer using a hexadecimal literal. The long variable is assigned a value with an L suffix.

Real

Real values are sequences of digits with a positive or negative sign, like integers. This also makes it possible to specify fraction values:

float realNumber = 12.5f;
realNumber = 1.25e+1f;
double realdNumber = 12.5;

As you can see, the literal in the last line, 12.5, is double by default, hence it needed to be assigned to a double variable, while the first two lines specify the literal in float types. You can also specify d or D as a suffix to define a double, like f or F for float and m for decimal.

Character

Character literals need to be kept inside a single quote. The value of the literal can be as follows:

  • A character, for example, c
  • A character code, for example, \u0063
  • An escape character, for example, \\ (the forward slash is an escape character)

String

A string is a sequence of characters. In C#, a string is represented by double quotation marks. There are different ways a string can be created in C#. Let's look at the different ways of creating a string in C#:

string s = "hello world";
string s1 = "hello \n\r world"; //prints the string with escape sequence
string s2 = @"hello \n\r world"; //prints the string without escape sequence
string s3 = $"S1 : {s1}, S2: {s2}"; // Replaces the {s1} and {s2} with values

The @ character can be placed as a prefix before a string to take the string as it is, without worrying about any escape characters. It is called a verbatim string. The $ character is used as a prefix for string interpolation. In case your string literal is preceded with the $ sign, the variables are automatically replaced with values if they're placed within { } brackets.

Programming syntax – conditions

Conditions are one of the most common building blocks of any program. A program cannot have single dimensions; comparison, jumps, and breaks are the most common forms of practice in C#. There are three types of conditions available:

  • if...else
  • switch-case
  • goto (lumps without condition)

If-else construct

The most commonly used conditional statement is the if-else construct. The building block of the if-else structure contains an if keyword, followed by a Boolean expression and a set of curly brackets to specify the steps to execute. Optionally, there could be an else keyword, followed by curly brackets for the code to execute when the if block is false:

int a = 5;
if (a == 5)
{
// As a is 5, do something
}
else
{
// As a is not 5, do something
}

The if-else construct can also have an else-if statement to specify multiple criteria for execution.

Switch-case construct

Switch-case, on the other hand, is almost similar to the if statement; in this statement, the cases will determine the execution step. In the case of switch, this always falls in a discrete set of values, and hence, those values can be set up:

int a = 5;
switch (a)
{
case 4:
// Do something;
break;
case 5:
// Do something;
break;
default:
// Do something;
break;
}

The switch case automatically picks the correct case statement, depending on the value, and executes the steps defined inside the block. A case need to be concluded with a break statement.

goto statements

Even though they are less popular and it is not advisable to use them, goto statements are used for unconditional jumps in the language and they are widely used by the language itself. As a developer, you can use a goto statement to jump to any location of your program with the context you have:

... code block
goto lbl1;
...
...
lbl1: expression body

The goto statement directly jumps to the location specified without any condition or criteria.

Programming syntax – loops

For a repetitive task during execution, loops play a vital role. Loops allow the programmer to define a criteria in which the loop will end or until the loop should execute, depending on the type of loop. There are four types of loops:

  • While
  • Do-while
  • For
  • Foreach

The while construct

A loop is used in the programming world to make a sequence of execution steps repeat itself until the condition is met. The while loop is one of the building blocks of the C# programming architecture and is used to loop through the body mentioned in curly brackets until the condition mentioned in the while criteria is true:

while (condition)
{
loop body;
}

The condition mentioned in the loop should evaluate to true to execute the loop for the next iteration.

The do-while construct

The do...while construct checks the condition after executing the step once. Even though the do...while loop is similar to the while loop, the only difference between a do...while loop and a while loop is that a do...while loop will execute the body at least once, even if the criteria is false:

do
{
loop body;
}
while (condition);

The for construct

The most popular loop in the language is the for loop, which handles complications by maintaining the number of executions of the loop efficiently within the block itself:

for (initialization; condition; update)
{
/* loop body */
}

The for loop has a few sections in the criteria. Each of these is separated by a semicolon (;). The first portion defines the index variable, which is executed once before executing the loop. The second portion is the condition that is executed in every iteration of the for loop. If the condition becomes false, the for loop doesn't continue its execution and stops. The third portion is also executed after every execution of the loop body and it manipulates the variable that was used in the for loop initialization and condition.

The foreach construct

The foreach loops are new to the language and are used to iterate over a sequence of objects. Even though this is purely syntactic sugar in the language, the foreach loop is widely used when dealing with collections. The foreach loop inherently uses an IEnumerable<object> interface and should only be used for objects implementing this:

foreach (type variable in collection)
{
//statements;
}

Contextual – break and continue statements

If you are working with loops, it is very important to understand two more contextual keywords that make it possible to interact with loops.

Break

This allows the developer to break the loop and take the context out of the loop, even though the criteria is still valid. The programming contextual keyword, break, is used as a bypass to break the loop in which it is getting executed. The break statement is valid inside loops and switch statements.

Continue

This is used to invoke the next iteration. The contextual keyword allows the developer to continue to the next step without executing any further code in the block.

Now, let's look at how we can use both of these contextual statements in our program:

var x = 0;
while(x<=10)
{
x++;
if(x == 2)continue;
Console.WriteLine(x);
if(x == 5) break;
Console.WriteLine("End of loop body");
}
Console.WriteLine($"End of loop, X : {x}");

The preceding code will skip execution of the body for the iteration value, 2, because of the continue statement. The loop will execute until the value of x is 5 because of the break statement.

 

Writing your first C# program in a console application

As you are now aware of the fundamentals and basics of the C# language, literals, loops, conditions, and so on, I think it is time to see a C# code example. So, let's start this section by writing a simple console application, compiling it, and running it using the C# compiler.

Open any notepad application that you have in your computer and type in the following code:

using System;

public Program
{
static void Main(string[] args)
{
int num, sum = 0, r;
Console.WriteLine("Enter a Number : ");
num = int.Parse(Console.ReadLine());
while (num != 0)
{
r = num % 10;
num = num / 10;
sum = sum + r;
}
Console.WriteLine("Sum of Digits of the Number : " + sum);
Console.ReadLine();
}
}

The preceding code is a classic example of calculating the sum of all of the digits of a number. It takes a number as input using the Console.ReadLine() function, parses it, and stores it into a variable, num, loops through while the number is 0, and takes modulus by 10 to get the reminder of the division, which is then summed up to produce the result.

You can see there is a using statement at the top of the code block, which ensures that Console.ReadLine() and Console.WriteLine() can be called. System is a namespace from the code, which enables the program to call the classes defined inside it without specifying the full namespace path of the class.

Let's save the class as program.cs. Now, open the console and move it to the location where you have saved the code.

To compile the code, we can use the following command:

csc Program.cs

The compilation will produce something like this:

The compilation will produce program.exe. If you run this, it will take the number as input and produce the result:

You can see that the code is being executed in the console window.

If we dissect how the code is being executed further, we can see that the .NET framework provides the csc compiler, an executable that is capable of compiling my C# code into a managed executable. The compiler produces an executable with MSIL as its content, and then, when the executable is being executed, the .NET framework invokes an executable and uses JIT to compile it further so that it can interact with the input/output devices.

The csc compiler provides various command-line hooks, which can be used further to add dynamic link library (dll) references to the program, target the output as dll, and much more. You can find the full functional document at the following link: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/listed-alphabetically.

 

Visual Studio as an editor

Microsoft has created a number of improvement toolsets that help in creating, debugging, and running programs. One of these tools is called Visual Studio (VS). Microsoft VS is a Development Environment that works with Microsoft languages. It is a tool that developers can rely on so that they can work easily with Microsoft technologies. VS has been around for quite some time, but the new VS has been totally redesigned and was released as VS 2019 to support .NET languages.

Evolution of Visual Studio

As time passed, Microsoft released newer versions of VS with more advantages and enhancements. Being a plugin host that hosts a number of services as plug-in, VS has evolved with a lot of tools and extensions. It has been the core part of every developer's activity. VS has been used by a large number of people who are not a part of the developer community, because they have found this IDE beneficial for editing and managing documents.

Types of Visual Studio

Microsoft has introduced different types or editions of VS. The difference between these editions are features and pricing. Among the editions, one is free, while others you have to buy. Consequently, knowing which edition provides which features and which edition is better for which type of work will make it easier for a developer to choose the edition right.

Let's look at a comparison between all versions of VS.

Visual Studio Community

VS Community edition is the free edition. This edition doesn't have some advanced features that are available in the others, but this Community edition is perfectly fine for building small/mid-sized projects. This is especially useful for a person who wants to explore the C# programming language, since they can download this edition for free and start building applications.

Visual Studio Professional

This version of VS is for your own development, with important debugging tools and all of the commonly used developer tools. So, you can use the IDE as your primary orientation and then you can go ahead!

Visual Studio Enterprise

VS Enterprise edition is for enterprises that require commercial levels of usage of the IDE. It supports special tools for testing, debugging, and so on. It also discovers common coding errors, generates test data, and much more.

Visual Studio Code

VS Code is a small, open source tool that is not a full IDE, but a simple code editor that has been developed by Microsoft. This editor is very lightweight and platform-independent. VS Code doesn't come with most of the features that the VS IDE has, but has sufficient features for developing and debugging an application.

For this book, we are going to use VS Community in most of our cases, but you can install any version that you wish. You can download the Community edition free of cost at the following link: https://www.visualstudio.com/downloads/.

Introduction to the Visual Studio IDE

After you first install VS, the VS installer will give you a few options regarding workloads, which means the type of applications you are going to develop using this IDE. For this book, we will only be creating C# console applications, so you can choose that option if you want. Now, let's start the VS IDE. After loading the IDE, it'll show you a start page with multiple options. Choose the option to create a new project.

New Project

After you choose new project, the New Project dialog box will appear. In this dialog box, a number of options will be available based on the packages that are currently installed with the IDE, as shown in the following screenshot:

In the preceding screenshot, the left-hand side groups are the types of templates that you can choose from. Here, I have chosen Windows Desktop and, from the middle window, I have selected Console App (.NET framework) to create my application. The bottom of the screen allows you to name the project and choose the location to store the project files. There are two checkboxes available, one of which says Create directory for solution when selected (by default, this remains selected). This creates a directory below the chosen path and places the files inside it, otherwise it will create files just inside the folder.

Use Search Installed Template to search for any template by its name at the right corner of the dialog box if you do not find your template. Since more than one framework can exist in one PC, the New Project dialog will allow you to choose a framework; you need to use this while deploying the application. It shows .NET framework 4.6.1 by default as the framework for the project, but you can change to any framework by selecting one from the drop-down menu.

Finally, click OK to create the project with the default files:

The preceding screenshot shows what a basic IDE looks like after the project is created. We can also see each section of IDE. The main IDE is composed of many tool windows. You can see some tool windows on all sides of the screen. The Task List window is at the bottom of the screen. The main IDE workspace is in the middle and forms the working area of the IDE. The workspace can be zoomed into by using the Zoom control in the corner of the screen. The IDE search box at the top of the screen gives you insight into finding options inside the IDE more elegantly and easily. We will now divide the whole IDE into those parts and explore the IDE.

Solution Explorer

The folders and files are hierarchically depicted in the Solution Explorer. Solution Explorer is the main window and lists the entire solution that is loaded to the IDE. This gives you a view of projects and files that have a solution for easy navigation in the form of a tree. The outer node of the Solution Explorer is itself a solution, then the projects, and then the files and folders. The Solution Explorer supports loading folders inside the solution and storing documents in the first level, too. The project that is set as startup is marked in bold.

There are many buttons present at the top of the Solution Explorer called toolbar buttons. Based on the file that's selected in the tree, the toolbar buttons will be enabled or disabled. Let's look at each of them individually:

  • Collapse All button: This button allows you to collapse all of the nodes below the node that's currently selected. While working with a big solution, it is often necessary to collapse a portion of the tree completely. You can use this feature without collapsing each node manually.
  • Properties: As a shortcut to the Properties window, you can select this button to open the Properties window and load the metadata associated with the currently selected node.
  • Show all files: A solution is generally mapped to a Folder structure on a directory in the filesystem. The files that are included in the solution are only shown on the Solution tree. Showing all files allows you to toggle between viewing all files in the directory and only the files that have been added to the solution.
  • Refresh: This refreshes the state of files in the current solution. The Refresh button also checks every file from the filesystem and shows its status accordingly (if any).
  • View Class Diagram: The class diagram is the logical tree of namespaces and classes rather than the files in the filesystem. When you select this option, VS launches the class diagram with all of the details of its properties, methods, and so on. The class diagram is useful for viewing all of the classes and their associations individually.
  • View Code: When you select a code file, the View Code button appears, which loads the code file associated with the current selection. For instance, when you select a Windows Form, it will show its code behind where the code needs to be written.
  • View Designer: Sometimes, based on the file type that is selected in the tree, the View Designer button appears. This button launches the Designer associated with the currently selected file type.
  • Add New Folder: As I have already stated, a solution can also contain folders. You can add folders directly to the solution by using the Add New Folder button.
  • Create New Solution: Sometimes, when working with large projects, you might need to create a subset of the entire solution and list only the items that you are currently working on. This button will create a separate Solution Explorer that is in sync with the original Solution Explorer, but projects a specific portion of the solution tree.

The solution tree in VS also loads the class structure of the project in the way it is organized in the filesystem. If you see a collapsed folder, you can expand it to see what is inside it. If you expand a .cs file, all of the members of that class are listed. If you just want to see how the classes are organized, you can use the class view window, but by using the Solution Explorer, you can see the classes, as well as the other elements inside its own hierarchy. You can open the Class View by choosing View | ClassView or pressing Ctrl + W and C, so that you can view only a portion of the class and its members:

Some files are shown in the solution as blank files (in our case, folders such as bin and obj). This means that these files exist in the filesystem but are not included in the solution file.

Each file shows additional information on the right-hand side of the tree node in the solution. This button gives extra information that's associated with the file. For instance, if you click on the button corresponding to a .cs file, it will open a menu with Contains. This will get the associated class view for that particular file in the solution. The menu can be pretty long, depending on the items that cannot be shown in the generalized toolbar buttons. When the solution loads additional information, there are forward and backward buttons, which can be used to navigate between views on the solution.

Main workspace area

The main workspace area is where you will actually write your code or apply different settings to your application. This section will open different kinds of files that you have in your project. This is the area which, as a developer, you will spend most of your time coding. You can open multiple files in this window. Different files will be shown in different tabs and you can switch from one tab to another just by clicking on the tab. If you need to, you can also pin tabs. You can make the tabs float if you think you need them that way, or you can also make it full-screen size so that you can focus on the code you are working on.

So, when you double-click on files in the Solution Explorer or choose Open from the context menu of the file, that file is opened in a tab in the main editor area. This way, you can open multiple files in separate tabs in the editor window and switch between them when needed. Each tab header contains a few fixed sets of items:

In the preceding screenshot, you can see that the tab header contains the name of the file (Program.cs) that links to the tab; it shows a * when the item needs to be saved, and it has a Toggle pinner button (just like all other IDE tool windows), which makes the tab sticky on the left side, and a close button. The title section also sometimes indicates some additional status, for example, when the file is locked, it shows a lock icon, and when the object is loaded from metadata, it shows that in square brackets, as in the preceding screenshot. In this section, as we keep on opening files, it goes in a stack of tab pages, one after another, until it reaches the end. After the whole area is occupied, it finally creates a menu on the rightmost corner of the workspace title to hold a list of all of the files that cannot be shown on the screen. From this menu, you can choose which file you need to open. Ctrl + Tab can also be used to toggle between the tabs that are already loaded in the workspace.

Below the title of the tab and before the main workable area are two drop-down menus. One has been loaded with the class that is opened in the IDE, and the right one loads all of the members that are created on the file. These drop-downs menu aid in easier navigation in the file by listing all of the classes that are loaded in the current file on the left, while on the right there is another that contextually lists all of the members that are there in the class. These two drop-downs menu are smart enough to update the drop-down values automatically whenever any new code is added to the editor.

The main workspace area is bounded by two scrollbars, which handle the overflow of the document. However, after the vertical scrollbar, there is a special button to split the window, as shown in the following screenshot:

The horizontal scrollbar, on the other hand, holds another drop-down menu that shows the current zoom percentage of the Editor. VS now allows you to scale your editor to your preferred zoom level. The shortcut for the Zoom feature is Ctrl + scroll mouse wheel.

Output window

The output window is placed on the bottom of the IDE (in general) and it opens up at various times when you either compile, connect to various services, start debugging, or do something that requires the IDE to show some code. The Output window is used by the IDE to display log and trace messages:

The Output window is docked on the bottom of the page, which lists various types of output. From the drop-down menu at the top, you can select which output you want to see in the output window. You will also have the option to clear the log if you want to display only the newer logs.

The Command and Immediate windows

The Command window is very similar to Command Prompt of the Windows operating system. You can execute commands using this tool. In the VS command line, you can execute commands on the project you are working on in. Commands are very handy and increase your productivity as you don't have to drag your mouse around to execute something. You can run a command to make this happen easily.

To open a Command window in VS, you can click on the View menu and then Windows. After this, select Command Window. Alternatively, you can use the keyboard shortcut, Ctrl + Alt + A, to open it. When you are in the Command window, you will see a > placed in front of every input. This is called a prompt. In the prompt, when you start typing, it will show an Intellisense menu for you. Start typing Build.Compile, at which point the project will be compiled for you as well. You can also use Debug.Start to start debugging the application. You can debug your application easily using commands. I will list some of the important commands that are used most often when debugging using the Command window:

  • ?: Tells you the value of a variable (you can also use Debug.Print to do the same)
  • ??: Sends the variable to the watch window
  • locals: Shows the locals window
  • autos: Shows the autos window
  • GotoLn: Sets the cursor to a specific line
  • Bp: Puts a breakpoint in the current line

Similar to the Command window, an Intermediate window lets you test code without having to run it. An Intermediate window is used to evaluate, execute a statement, or even print variable values. To open the Immediate window, go to Debug | Windows and select Immediate.

Search option in IDE

On the very top-right corner of the screen, you will find a new Search box. This is called the IDE search box. VS IDE is vast. There are thousands of options available inside of it that you can configure. Sometimes, it is hard to find a specific option that you want. The IDE search feature helps you find this option easier:

The search option will list all of the entries related to VS IDE options, and you can easily find any feature you are looking for here.

 

Writing your first program in Visual Studio

VS is the IDE where developers mostly code while working with the C# language. As you already have a basic idea of how VS works, let's write our first program in VS. Let's create a console application, name the solution MyFirstApp, and press OK. The default solution template will be automatically added, which includes one Program.cs with the Main program, and a number of other files.

Let's build a program that generates an ATM machine. There will be a menu that has three options:

  • Withdraw
  • Deposit
  • Balance check

The withdrawal will be performed on the balance (initially $1,000) and a deposit will add an amount to the current balance. Now, let's see what the program looks like:

class Program
{
static void Main(string[] args)
{
int balance, depositAmt, withdrawAmt;
int choice = 0, pin = 0;
Console.WriteLine("Enter your ledger balance");
balance = int.Parse(Console.ReadLine());
Console.WriteLine("Enter Your Pin Number ");
pin = int.Parse(Console.ReadLine());

if(pin != 1234)
{
Console.WriteLine("Invalid PIN");
Console.ReadKey(false);
return;
}

while (choice != 4)
{
Console.WriteLine("********Welcome to PACKT Payment Bank**************\n");
Console.WriteLine("1. Check Balance\n");
Console.WriteLine("2. Withdraw Cash\n");
Console.WriteLine("3. Deposit Cash\n");
Console.WriteLine("4. Quit\n");
Console.WriteLine("*********************************************\n\n");
Console.WriteLine("Enter your choice: ");
choice = int.Parse(Console.ReadLine());

switch (choice)
{
case 1:
Console.WriteLine("\n Your balance $ : {0} ", balance);
break;
case 2:
Console.WriteLine("\n Enter the amount you want to withdraw : ");
withdrawAmt = int.Parse(Console.ReadLine());
if (withdrawAmt % 100 != 0)
{
Console.WriteLine("\n Denominations present are 100, 500 and 2000. Your amount cannot be processed");
}
else if (withdrawAmt > balance)
{
Console.WriteLine("\n Sorry, insufficient balance.");
}
else
{
balance = balance - withdrawAmt;
Console.WriteLine("\n\n Your transaction is processed.");
Console.WriteLine("\n Current Balance is {0}", balance);
}
break;
case 3:
Console.WriteLine("\n Enter amount you want to deposit");
depositAmt = int.Parse(Console.ReadLine());
balance = balance + depositAmt;
Console.WriteLine("Your ledger balance is {0}", balance);
break;
case 4:
Console.WriteLine("\n Thank you for using the PACKT ATM.");
break;
}
}
Console.ReadLine();
}
}

Now, let's illustrate the program. The program requests a PIN number before opening the ATM machine. The PIN is not checked and can be anything. Once the program starts up, it creates a menu in the front of the console with all of the desired options.

You can see that the entire code is written inside a while loop, as it ensures that the program is kept alive for multiple executions. During execution, you can choose any of the options that are available and perform the action associated with it.

To execute the program, just click on the Run button on the toolbar of the IDE:

If the program does not run automatically, you can look at the Error List window to figure out the actual issue. If you made a mistake in the code, VS will show you the appropriate error message and you can double-click on this to navigate to the actual location.

How to debug

If you have heard about VS, you must have heard about the debugging capabilities of the IDE. You can start the program in debug mode by pressing F10. The program will start in debug mode with the context in the first line. Let's execute a few of the lines. This will look as follows:

The highlighted line in the code editor workspace depicts the line where the current execution has halted. The line is also marked with an arrow on the very left of the code editor. You can continue pressing F10 or F11 (step into) buttons to execute these lines. You must inspect the Locals window to find out about all of the values of the local variables during their execution.

Debugging through code

For really advanced users, the .NET class library opens up some of the interesting debugger APIs that you can invoke from your source code to call a debugger manually.

From the very beginning of a program, there is a DEBUG preprocessor variable, which determines whether the project was built in debug mode.

You can write the code in the following way:

#IF DEBUG
/// The code runs only in debug mode
#ENDIF

The preprocessor directives are actually evaluated during compile time. This means that the code inside IF DEBUG will only be compiled in the assembly when the project is built in debug mode.

There are other options such as Debug.Assert, Debug.Fail, and Debug.Print. All of these only work during debug mode. In release mode, these APIs won't be compiled.

You can also call the debugger attached to the process if there is any such process available, using the Debugger.Break() method, which will break in the debugger at the current line. You can check the debugger. IsAttached is used to find out whether the debugger is attached to the current process.

When you start debugging your code, VS launches the actual process as well as one in .vshost in its filename. VS enhances the experience of debugging by enabling Partial Trust's debugging and improving the F5 experience by using the .vshost file. These files work in the background to attach the actual process with a predefined app domain for debugging to make a flawless debugging experience.

.vshost files are solely used by the IDE and shouldn't be shipped in an actual project.

VS needs Terminal Services to run these debuggers as it communicates with the process even when it is in the same machine. It does this by using a Terminal Service to maintain a seamless experience with both normal and remote debugging of a process.

 

Summary

In this chapter, we looked at the basics of the C# language and introduced the VS Editor. We also tried to write our first program using the command line and VS.

In the next chapter, we will continue this discussion by looking at OOP concepts and techniques, which will allow us to write more classes.

About the Author

  • Raihan Taher

    Raihan Taher is a young, skilled software developer who has gained extensive experience by being involved in a variety of projects throughout his career. His particular areas of interest are web development and software architecture. His ability to write clean code and observe best practices in software development are his major assets. Throughout his relatively short career, he has worked for a number of renowned multinational companies, including Accenture, Quintiq (Dassault Systmes), and SEB Pension. His desire to share his knowledge has encouraged him to write technical blogs, create online video courses, write books, and conduct technical training sessions. His courses, blog posts, and books have already been well received by many new developers. As regards the future, his vision is to discover and establish best practices for software development and share those with fellow developers. His ability to write quality software is what makes him accomplished. Aside from this, he is an avid reader and is excited by the challenge of learning new things. He always pushes himself to learn and implement new technologies in his work. Keeping himself up to date with new technologies and implementing those in his work makes him an expert in the area of cutting-edge technologies. He also loves to travel and explore adventurous places with his wife.

    Browse publications by this author

Latest Reviews

(2 reviews total)
"Hands-On Object-Oriented Programming in C#" is an overview of object oriented techniques. Although the topic selection is good, the depth of material covered is shallow. Recommended for a quick survey or brief review.
Well written. I'm half way through and enjoying it. I wish there were more complete examples though.

Recommended For You

Hands-On Object-Oriented Programming with C#
Unlock this book and the full library for FREE
Start free trial