The .NET framework is very large, and sometimes it is hard to decide whether to code something or use an existing component of the framework. Sometimes it is faster to code, but when production workload and reliability come into play, the perspective is different. An overview of what .NET offers is fundamental knowledge. It is hard to keep track because .NET evolves very fast. This article discusses the essentials from which the .NET Framework is built.
.NET 1.0
Common Language Runtime
The most significant characteristic of the .NET Framework is its ability to use classes and call methods across different languages. Almost everything is written in C# now, but when this language is surpassed by something revolutionary, it will not be necessary to rewrite all C# code and libraries.
All languages are compiled into Common Intermediate Language (CIL), which is then compiled to native code for the processor architecture where the code runs. That’s why C# is called a managed language. The .NET runtime is the fastest compared to others. It is only about 5% slower than native code, but the benefits are huge.
Garbage Collector
The garbage collector frees us from the old C++ world where it is necessary to manage memory manually. The .NET framework takes care of it. Since .NET 4, garbage collection is processed in a separate thread, so the performance is more than sufficient.
ADO.NET
ADO (ActiveX Data Objects) was part of COM (Component Object Model) for accessing data sources. ADO.NET shares only the name with ADO and is otherwise entirely different. It is a framework in the System.Data
namespace for accessing mainstream databases. Every major database manufacturer provides a provider for ADO.NET, which means it is supported by the .NET Framework.
String
In the .NET framework, there is only one string
type used to represent string values. Internally, a string is represented in UTF-16 format, not UTF-8, and each unique string value exists as a single instance in memory due to string interning. This might seem straightforward, but it is quite different from the manual memory management required in the C++ world.
.NET 1.1
Regular Expressions
Regular expressions provide a powerful, flexible, and efficient technique for string processing. When you need to extract something from a string, consider using regular expressions. Although the theory behind them is quite complex, it is worth learning. The .NET implementation is compatible with Perl 5 and supports right-to-left matching and on-the-fly compilation.
1st XML processing
The XmlDocument
class in the System.Xml
namespace provides functionality for parsing and browsing XML documents. It supports the XPath language for data extraction.
HttpUtility
The HttpUtility
class is a very important static class used for encoding and decoding URL arguments when processing web requests. One particularly useful method is HtmlDecode
, which replaces HTML entities with their equivalent Unicode characters.
String Builder
Don’t even think about concatenating several strings in a loop without using the StringBuilder
class. It uses character arrays internally and is extremely optimized. Of course, writing strings directly to the stream when possible avoids high memory consumption.
.NET 2.0
Generics
C# is a very type-safe language. Generic algorithms are abstracted and require specific type features. These features can be described by an interface or an abstract class. For example, the most common is IEnumerable<T>
, which represents a collection of objects.
Event Log
EventLog is the unified logging system for Windows. Instead of manually creating and truncating log files or filtering and categorizing data, the EventLog
class handles these tasks.
Configuration Manager
The ConfigurationManager
class contains connection strings and other constants that you may want to change without needing to recompile. The referenced DLL assembly can also access the main executable assembly’s configuration file. In ASP.NET, the configuration file is the web.config
file.
SQL Server
You can write SQL Server stored procedures in .NET languages. This can sometimes be useful, but the .NET assembly must be stored in the database via a T-SQL command. However, it is not limited to version 2.0; newer versions of .NET are also supported.
Nullable Types
There are reference types and value types. This distinction is very important in the C++ world, but it is less frequently a concern in C#. Reference types are objects, while value types include int
, long
, byte
, bool
, short
, char
, and so on. Only reference types can be assigned null
by default, as they point to a memory location. Value types, on the other hand, are initialized with a default value, which can sometimes be awkward. This is where nullable types come in handy.
.NET 3.0
XAML
XAML allows creating a user interface in an HTML-like language. This declarative approach has many advantages. One of them is data binding, which is essential for the MVVM design pattern. XAML is also accelerated by a graphics card, making it very fast.
Web Services
Web services are useful for invoking remote methods on a server from a client. They are standardized, making them ideal for interoperability scenarios. These services are often referred to as WCF (Windows Communication Foundation) Services.
Workflow
A workflow is an activity model that can represent anything from a business process to a Team Foundation Server build. The advantage is that activities are defined declaratively using XAML instead of code. This allows modifications to be made as easily as changing a configuration file, without the need to recompile.
Feed Processing
The SyndicationFeed
class provides support for RSS 2.0 and Atom 1.0 syndication formats.
.NET 3.5
Language Integrated Query
LINQ is a killer feature for other languages and a must-have capability once you get used to it. LINQ is like SQL for object-oriented programming. Operations like sorting, taking the top n items, and finding items that satisfy certain conditions can all be done very easily and elegantly in a single line with LINQ.
Entity Framework
When you learn LINQ and realize it is much more comfortable than SQL, you will want to use LINQ for database queries. That’s what the Entity Framework is made for. Since version 4, you can write your classes to match database tables and use them instead of the database schema. You can also generate the database schema from them, which is called the Code-First approach. When you need to update the database schema later, you can use Database Migrations. This simple method describes schema changes and manages migrations to the latest schema automatically with Entity Framework.
XML Processing
The XDocument
class in the System.Xml.Linq
namespace is designed to be used with LINQ. XDocument
provides in-memory APIs rather than streaming ones.
Reactive Extensions
Rx is a library for composing asynchronous and event-based programs using observable collections and LINQ-style query operators. It is not embedded into the .NET Framework yet, but it is significant enough to be listed here. Compared to TPL, which was introduced later, Rx is designed to work with data streams, while TPL is familiar with the producer-consumer pattern.
.NET 4.0
Managed Extensibility Framework
MEF is integrated into the .NET Framework in the System.ComponentModel.Composition
namespace. It allows using assemblies as modules. When you need to create a modular system, MEF takes care of assembling all the modules.
Parallel Extensions
Parallel Extensions include Parallel LINQ (PLINQ) and the Task Parallel Library (TPL). When you have a lot of work to do, it is worth using a task-based approach. Split the work into many small tasks and run them as needed. Run them sequentially or in parallel, without managing threads manually. The Parallel
class takes care of the processor count and the efficient number of concurrent threads. When programming at this level, you should use appropriate collection classes, such as concurrent collections in the System.Collections.Concurrent
namespace.
Dynamic Language Runtime
You can use a dynamic
type when you need to interact with a type-lacking environment, dynamic languages, or other scenarios. It is very useful when interacting with the COM environment because it does not provide IntelliSense.
Lazy Initialization
When a program contains something time-consuming to initialize, which may not be used during the program’s lifetime, using lazy initialization is a very good idea. A Lazy<T>
object is initialized when it is accessed for the first time.
.NET 4.5
Asynchronous Pattern
Asynchronous programming was always possible in .NET, but it was cumbersome until .NET 4.5. This version introduced the await
keyword, similar to F#’s pipe-forward operator. When threads are just waiting for a server response, they do nothing but consume machine resources. Separate threads are good for large computing tasks, but not for waiting and blocking operations. The await
keyword means: “Hey, this will take a while, do something useful in the meantime.”
Simple Web Programming Interface
The HTTP protocol has become a widespread standard for data exchange due to its useful features that other protocols lack. Use methods that take a single Uri
argument to manipulate data. For example:
XmlDocument.LoadFromUriAsync
downloads and parses the XML file.WebClient.DownloadStringAsync
serves downloaded content directly as a string.WebClient.DownloadFileAsync
saves downloaded content to local storage.WebClient.UploadFileAsync
uploads a file to the server.WebClient.PostAsync
is the easiest way to send a POST request.
JavaScript Object Notation
JSON has become a lightweight, universal object serialization format compared to XML. The JsonObject
class is a counterpart to the very robust Json.NET
library used with older .NET versions.
AtomPub
The AtomPubClient
class enables HTTP CRUD access to web resources using the AtomPub protocol.
Feed Processing
Like its predecessor, the SyndicationClient
class provides support for RSS 2.0 and Atom 1.0 syndication formats.
XML Processing
The XmlDocument
class in the Windows.Data.Xml.Dom
namespace provides easier XML document manipulation than before. Inspired by JavaScript’s HTML Document Object Model, it contains GetElementById
and GetElementsByTagName
methods. Web developers will likely appreciate the approach this class provides.
TPL Dataflow
The TPL Dataflow (TDF), found in the System.Threading.Tasks.Dataflow
namespace, is the foundational layer for asynchronous and concurrent programming using Task
provided in the Task Parallel Library. It provides a high-level approach necessary to manage large amounts of data.