Generics is a concept so ingrained into .NET that we can't do without it. In this module we'll explain the simple and more advanced things of Generics.
- Using Generics
- Creating Generics
- Understanding Covariance and Contravariance
Delegates and Events
Storing functions in variables, that is exactly what delegates allow us to do. This concept is used in lots of locations, especially when using asynchronous programming. Events are based on delegates, so whenever something interesting happens in a UI (eg. mouse click) and we want to react on it, we need delegates to handle it correctly.
- Creating Delegates
- Using Delegates
- Multicast Delegates
- Creating Events
- Using Events in a UI
Advanced Language Features
.NET 3.5 introduced a couple of features that make the life of developers a hell of a lot easier. We'll explore them in this chapter.
- Type inference
- Anonymous types
- Anonymous methods
- Lambda expressions
- Extending existing classes with Extension methods
LINQ allows to write queries that are very familiar to SQL queries. This makes certain operations like filtering and sorting data very easy. This concept is used in lots of locations, whether it is to connect to SQL databases of reading data from Active Directory
- What is LINQ?
- LINQ to Objects, SQL, Entity Framework and XML
LINQ Syntax Fundamentals
- LINQ's Enumerable class
- Func delegate
- Query syntax vs. Method syntax
- Deferred Query Evaluation
- Querying data using LINQ
- Group and Join operators
- Don't forget the let operator!
Useful language features in C# 6 and VB 14
Together with the coming of Visual Studio 2015 a couple of new language features are introduced to .NET. Again these features make the life of a developer easier, so it's worth having a look at them.
- String interpolation
- New nameof keyword
- Property enhancement
- Null-conditional (Elvis) operator
- Expression bodied functions
- Static using statements
- Async exception handling
- Exception filters
Programming the Garbage Collection
When you create an object in .NET, the framework takes care of memory management for you. What actually happens with objects when .NET decides to remove them from memory? That's what Garbage Collection is all about and we'll have a look at why it is important to understand it correctly.
- The lifecycle of a class instance
- GC class and members
- GC ressurection
- Forcing a garbage collection
- Weak References
- The Dispose pattern
- Garbage Collection for Unmanaged resources
In todays world where devices get more CPUs instead of the amount of Hz they produce, we need to be able to harvest this power. In the modules about multi-threading we'll discuss the advantages and problems you will encounter when using concurrency.
- What is concurrency?
- Understanding processes and threads
- Different kinds of concurrency
- Scheduling threads
Multithreading in .NET
Everyone starts by learning the fundamentals. The Thread class is the most basic implementation for creating concurrency. It is important to have an understanding of this class so you can understand and appreciate the libraries that came afterwards.
- The Thread class, ThreadStart delegate
- Exceptions and threads
- Understanding thread pooling
Using variables in a multi-threaded environment can be very dangerous and/or confusing. In this module we'll explain what can go wrong and how to avoid it.
- Race conditions and dead locks
- Avoiding race conditions
- Synchronizing threads: locks, monitors, signals, ...
- Synchronization guidelines
- Thread safety in .NET
Since .NET 4.0 we have a newer way of creating a multi-threaded application. We can make use of tasks to do our bidding. There are again advantages and disadvantages to using this library and we'll explore them in this module.
- What are tasks?
- Waiting asynchronously
- Dealing with exceptions
- Task cancellation
The new async and await syntax explained
Async and await are a language construct existing since .NET 4.5. This construct allows asynchronous programming in a newer and refreshing way.
- What is asynchronous programming?
- Invoking any method, synchronous and asynchronous
- Async guidelines
Asynchronous programming in .NET
- A history of asynchronous programming in .NET
- Understanding SynchronizationContext
- How to make your sync methods async
- Async guidelines
In a multi-core environment, being able to split data so every core is working on something is incredibly useful. This module explores a library created to do just that.
- What is parallel programming?
- Concurrent collections
- Parallel LINQ
Reactive Extensions, a feature a bit complex to understand, but very powerful and hard to get back from. It is sometimes called LINQ to events, because we think of asynchronous operations or events as a stream of data. An observable collection that will, from time to time, have a new interesting event pop up that we can react to.
- Push vs. Pull
- Reactive Extensions = LINQ to events
- Understanding IObservable<T> and IObserver<T>
- Using LINQ with Rx
- Building your own Rx Extensions
Tips and Tricks for Debugging
Most developers spend the majority of their time on debugging. If we can make this process easier and give the developers more control, we should definitely do that. In this module we'll look at some features in Visual Studio that can help us a lot during debug time.
- Advanced Breakpoints
- Using the immediate and watch window
- Debugging multi-threaded code
Visual Studio IntelliTrace
The famous "It works on my machine" saying. Lots of developers have used it, but not anymore. IntelliTrace is a feature in Visual Studio allowing us to do debugging on a session of a user on a different machine. In this module we'll talk about activating and using it in our software process.
- Reproducing Bugs in Software
- What is IntelliTrace?
- Enabling IntelliTrace
- Post-mortem debugging
- IntelliTrace in production
Streams, files and serializing data. All very important aspects when you create an application. The next couple of modules will talk about allowing data to be persisted, encrypted or sent over to another party for communication.
- What is a Stream?
- Why do we need Streams?
- Using Streams
- File and FileInfo class
- Directory and DirectoryInfo class
- Using the FileSystemWatcher class
- Path class
Serialization in .NET
- Serialization and deserialization patterns in .NET
- Using Formatters for serialization
- Using JSON.NET
- Serializing Exceptions
Attributes and Reflection
In this module we'll talk about using attributes to add metadata to almost everything in .NET. Metadata is of course only useful if we can actually interpret it and that's where reflection comes into play. Reflection is a powerful feature used in lots of libraries and applications.
- What are attributes?
- Applying attributes
- Common predefined attributes
- Building custom attributes
- What is reflection?
- Retrieving attribute values
Expressions and static reflection
Making use of Expressions to dynamically create code that can be run when we want to is very powerful. It is a feature used by LINQ for example to translate queries for a database or other system.
- What are expressions?
- How does LINQ to database work?
- Using Static Reflection
- Getting the name of a property
Using the Dynamic Language Runtime
.NET is a statically typed language, or is it? With the coming of .NET 4, Microsoft has introduced a new keyword allowing us to use dynamically typed variables. In this module we'll explain the use cases for it and how powerful it actually is.
- Understanding the dynamic keyword
- Building your own dynamic types