
This video gives glimpse of the entire course.
As a developer, you have certainly heard about many programming languages, such as C#, Java, C++, C, PHP, or Ruby. In all of them, you can use various data structures, as well as implement algorithms, to solve both basic and complex problems.
In this video, we will introduce the basic information about a few programming languages and data types.
Understand the concept of Object, class and interface
Example: Declare a variable in the C# programming language
Create enumeration for available languages or supported currencies and use defined enumeration as a data type
In this video, we will learn the steps of installing Visual Studio Community 2017 and setting up the environment.
Create a new project
Understand the properties and functions of the IDE
In this video we will learn operations related to the standard output stream performed using methods of the Console static class from the System namespace, namely Write and WriteLine.
Using ReadLine method, read data of other types, such as int.
Call the Write method and pass the text as a parameter
The arrays have a lot of possibilities. However, generic lists available while developing in the C# language are even more powerful. A single-dimensional array stores a collection of items of the same type, which are accessible by an index.
Declare and initialize array with an integer and default value
Example – month names
The arrays in the C# language do not need to have only one dimension. It is also possible to create two-dimensional or even three-dimensional arrays.
Declare and initialize two-dimensional array with 5 rows and 2 columns
Example – multiplication table
Example – game map
In this video we will look at the last variant of arrays that is Jagged array Also we will understand the difference between the arrays
Analyze array by observing the diagram
Example – yearly transport plan
There are many algorithms that perform various operations on arrays. However, one of the most common tasks is sorting an array to arrange its elements in the correct order, In this video, we will look at a couple of approaches, including selection sort and insertion sort
Divide array into two parts, namely sorted and unsorted
Test implementation of the selection sort algorithm
In this video we will proceed further to learn the remaining approaches of the sorting algorithm. Use two loops, and compare adjacent elements
Use two loops, and compare adjacent elements
Use recursion to call sorting method for subarrays
Arrays are really useful data structures and they are applied in many algorithms. However, in some cases their application could be complicated due to their nature, which does not allow to increase or decrease the length of the already-created array.
Use foreach loop to iterate through all items
Generic list Example – average value
Generic list Example – list of people
In this video we will introduce 2 types of lists that is Sorted and linked list. Sorted list stores the key-value pairs, you have also access to the Keys and Values properties. Particular keys and values can be easily obtained using the index and the [] operator.
Add an element to the collection using the Add method
Use ContainsKey and ContainsValue for checking whether the collection contains an item with a given key or value
Example – address book and book reader
In this video, we will look at the implementation of the circular-linked list that can be created as a generic class and extends LinkedList
Use CircularLinkedListEnumerator class and implement GetEnumerator method
Example – spin the wheel
Create a new instance of the CircularLinkedList class and add eight values
In this video, we will learn the basic concept of stack. It is an easy-to-understand data structure and can be represented using the example of a pile of many plates, each placed on top of the other. You can only add a new plate to the top of the pile, and you can only get a plate from the top of the pile.
Learn stack with diagrammatic representation
Example – reversing words
Example – Tower of Hanoi
In this video, we will learn Queue. The queue data structure operates in exactly the same way. You can only add new elements at the end of the queue (the enqueue operation) and remove an element from the queue only from the beginning of the queue (the dequeue operation).
Introduce Queue concept with diagrammatic representation
Example – call center with a single consultant
Example – call center with many consultants
A priority queue makes it possible to extend the concept of a queue by setting priority for each element in the queue. Priority can be specified simply as an integer value. However, it depends on the implementation whether smaller or greater values indicate higher priority.
Analyzing the diagram, learn the concept of priority queue
Example – call center with priority support
One of the most important assumptions of the hash table is the possibility of very fast lookup for a Value based on the Key, which should be the O(1) operation. To achieve this goal, the Hash function is used. It takes the Key to generate an index of a bucket, where the Value can be found.
Get access to a particular element using the indexer
Cast the returned result to the proper type (for example, string)
Example – phone book
In the previous video, you got to know the Hashtable class as a non-generic variant of the hash table-related classes. However, it has a significant limitation, because it does not allow you to specify a type of a key and a value. Both the Key and Value properties of the DictionaryEntry class are of the object type.
Create new instance of the Dictionary class
Use indexer to get access to a particular element within the collection
Example – product location
Both non-generic and generic variants of the hash table-related classes do not keep the order of the elements. For this reason, if you need to present data from the collection sorted by keys, you need to sort them prior to presentation. However, you can use another data structure, the sorted dictionary, to solve this problem and keep keys sorted all the time.
Get access to the element and add new element or update a value of the existing one
Example – definitions
In this video, we will understand the basic concept of Sets. While developing applications in the C# language, you can benefit from high-performance operations provided by the HashSet class.
Understand the concepts of Hash sets
Example – coupons
Example – swimming pools
The "sorted" set can be used if you want to have a sorted collection of distinct objects without duplicated elements. The suitable class is named SortedSet
Example – removing duplicates
A tree consists of multiple nodes, including one root. The root does not contain a parent node, while all other nodes do. The C#-based implementation of a basic tree seems to be quite obvious and not complicated. To do so, you can declare two classes, representing a single node and a whole tree
Use Root property to get access to root node, and Children property to obtain data of other nodes
Example – hierarchy of identifiers
Example – company structure
Each node in a basic tree can contain any number of children. However, in the case of binary trees, a node cannot contain more than two children.
Assign a default value to the Children property in the constructor
Example – simple quiz
Binary search tree data structure, which is also referred to as BST. It is a kind of a binary tree that introduces two strict rules regarding relations between nodes in the tree. The implementation of a BST is more difficult than the previously-described variants of trees.
Represent single node in a tree
Represent whole tree by an instance of the BinarySearchTree class
Check whether the tree contains a node with a given value
This video provides an overview of the entire course.
SOLID principles can upgrade the code someone writes. The problem is, they are complex.
Describe what SOLID means
Brief summary of all principles
It’s fairly common for developers to write classes that do more than one thing.
Demonstrate an example of such a class
Refactor the class to adhere to the single responsibility principle
The open/closed principle is rarely used as developers keep adding stuff to their classes.
Describe what closed to modification means
Explain what open to extension means
Demonstrate a comprehensive example
The Liskov substitution principle is perhaps the hardest of the five. We need to provide a high quality explanation without making the video long and boring.
Theoretical examination
Use a quiz app example
According to the interface segregation principle, a class shouldn’t be forced to implement a method that it does not need or can’t implement.
Go straight to an example of an interface that is wrongfully used
Split that interface into two interfaces
Implement them separately
Dependency Inversion is so vital that a part of it, Dependency Injection will have its own section. But for now we need to demonstrate how important it is.
Explain Dependency Inversion and loose coupling in theory
Demonstrate tight coupling’s downsizes
Implement a service the correct way by connecting to an abstraction
In this video, we will work almost exclusively with patterns so introductions are in order.
Describe design patterns in general
Briefly explain each creational pattern that we are going to study
Sometimes we need to only have a single instance of a class.
Describe singleton theoretically
Implement singleton with a PrimaryPlayer class
Note limitations and downsides
Following the single responsibility principle, our consumer classes shouldn’t be the ones responsible for knowing how to instantiate classes that we need.
Describe the factory pattern in theory
Create an EnemyFactory
We need to take care of a few stuff in the course project. This presents a nice opportunity to involve the concept of Loose Coupling.
Create an Iweapon interface
Create different weapon implementations
Add them to the player and attack an enemy
The Object Pool is a great pattern to avoid having to be constantly initializing our enemy classes every time we need them.
Modify the EnemyFactory to work with object pools
Create a pool for the Zombie class
Add a reclaim mechanism
Not all C# developers are familiar with Dependency Injection and since we are dedicating a whole section on it we better spend a video trying to explain the most interesting topics.
Explain Dependency Injection thoroughly
Show a very simplistic visual example
There’s great value in creating a Custom IoC Container. The viewer will get to understand the inner workings of Dependency Injection.
Describe the vital operations that an IoC Container needs to be doing
Implement the registration method
Implement the Dependency resolution method
The Custom Container is good for educational purposes but we need something more robust. So we have to move on to the built-in ASP.NET Core IoC Container.
Create an ICardsService interface
Create a CardsService concrete implementation
Register the implementation as a Singleton and inject it to a controller
The ASP.NET Core Container offers three different registration strategies. We need to make the distinctions clear.
Describe the three strategies and decide on the best one for the task at hand
Create a method that tests the API connection
Consume the API project from the console application
Sometimes we want to combine objects while maintaining their types. To do that we use the decorator pattern.
Use figures to explain what the decorator pattern does
Use the decorator pattern to decorate cards with items
We must make use of a foreign interface. We need to make it work with what we already have. That’s what the adapter pattern is for.
Introduce a 3rd party library to the project
Work with the adapter pattern to circumvent it
The Gameboard class is getting more and more complicated.
Theoretical introduction to the facade pattern
Use the facade pattern to simplify the Gameboard
We want to provide a way to iterate through decks of cards as well as decks of decks.
Describe the composite pattern
Create a common IComposite interface
We want to quickly and easily fetch data from the API in a loosely coupled way.
Decouple the service from the implementation
Use a proxy class to fetch the data
Sometimes we need to choose an algorithm at runtime. The strategy pattern is perfect at doing that.
Describe the need for the strategy pattern
Create two strategies for showing messages
Watching the primary player’s health is better than just using strategy.
Create a HealthChanged event
Register observers
Combine them with the strategy pattern
We need a way to encapsulate the battles between players and enemies as well as cards and enemies.
Create an ICommand interface
Create two command implementations
Group them into a list and execute
The template method defines an abstract base class that forces sub-classes to only implement part of the functionality.
Create a template for rendering the battlefield
Create different battlefields that will be randomly generated
The state pattern offers a convenience class to store data about your sessions.
Create a state class
Store statistics there
Data structures allow you to organize data efficiently, but critical to various problems and their suitable implementation can provide a complete solution that acts like reusable code; whereas design patterns are reusable solutions to common programming problems where they speed up the development process by providing tested, proven development paradigms.
This course follows a practical approach, where you'll first start learning about arrays, lists, dictionaries, and sets together with real-world examples of your application. Then, you'll be learning creational design patterns, patterns related to the creation of objects, such as Singleton, Factory, and Dependency Injection. Next, you'll gain deep knowledge about dependency Inversion pattern, which will teach you how to write highly extensible, maintainable, and testable code along with insights into structural & behavioral design patterns.
By end of this course, you will be able to build your own desktop applications in C# 7.x much faster and with ease also improve the maintainability and testability of your application and gain the confidence to start a new project with Functional Programming paradigms.
Contents and Overview
This training program includes 2 complete courses, carefully chosen to give you the most comprehensive training possible.
The first course, Beginning Data Structures and Algorithms in C# you will learn how to use various data structures while developing in the C# language as well as how to implement some of the most common algorithms used with such data structures. Initially, you will get to know arrays, lists, dictionaries, and sets together with real-world examples of your application. Then you will learn how to create and use stacks and queues. In the following part of the book, more complex data structures will be introduced—trees and graphs—together with some algorithms for searching the shortest path in a graph. We will also discuss how to organize code in a manageable, consistent, and extendable way. By the end of the course, you will have learned how to build components that are easy to understand, debug, and use in different applications.
The second course, Design Patterns using C# and .NET Core starts at the nuts-and-bolts level and shows you everything through to advanced patterns and features, going in-depth to give you the knowledge you need. You will begin this course with an introduction to SOLID principles, which will introduce you to clean-code concepts and will elevate your skills. With this knowledge in your toolbox, you will be ready to move on to studying creational design patterns, patterns related to the creation of objects, such as Singleton, Factory, and Dependency Injection. You will then acquire more in-depth knowledge of one specific creational pattern, the Dependency Inversion pattern, which will teach you how to write highly extensible, maintainable, and testable code. Moving on, you will get your hands dirty with structural design patterns and you will complete this course by learning the last group of patterns: behavioral design patterns. By the end of this course you will be very confident in implementing a new feature in C# and .NET Core because, every time you have a problem, the correct design pattern will spontaneously come to mind.
About the Authors:
Marcin Jamro, PhD, is an entrepreneur and researcher, as well as a developer and architect of various kinds of applications. He is the President of the Board at TITUTO Sp. z o.o. [Ltd.] in Rzeszów, Poland. Marcin is interested in many aspects of computer science, including software engineering and project management. He is the author of two other books—Windows Phone 8 Game Development (2013) and Windows Application Development Cookbook (2017), both by Packt Publishing. Marcin has published several papers, participated in many conferences, organized a few of them, and participated in two internships at Microsoft in Redmond, USA. He has MCP, MCTS, and MCPD certificates.
Dimitris Loukas is a software engineer currently writing Single Page Applications and using the latest JavaScript with Aurelia, Angular, C#, and .NET Core for a trading software firm. He has worked for two start-ups in the past, is active in the open source community, and loves taking up small side-projects. He has mastered Angular, Aurelia, and Vue.JS and is now interested in entering the ReactJS world. He is an early adopter of .NET Core and is fascinated by modern JavaScript and where the web is going.