This chapter is from the book

Time to set yourself up for a successful journey through the world of .NET development using C#. An obvious first thing to tackle is to install the .NET Framework and the necessary tools so that we can start running and writing code. One tool we pay a fair amount of attention to is Visual Studio 2012, but we cover other useful tools, too.

To get our hands dirty, we write a simple C# application and highlight some of the important language elements, go through the process of building it using various tools, and look at how we can debug code.

Installing the .NET Framework

The first logical step to get started with writing code targeting the .NET Framework is to install it on your development machine. At this point, let’s skip the in-depth discussion on how to deploy the .NET Framework to the machines where your application code is to run ultimately, be it a client computer, a web server, or even the cloud.

The .NET Framework Version Landscape

Over the years, various versions of the .NET Framework have been released. In this book, we cover the latest (at the time of this writing) release of the .NET Framework, version 4.5, which goes hand in hand with the Visual Studio 2012 release.

Does that mean you can’t use the knowledge you gain from .NET 4.5 programming to target older releases of the framework? Certainly not! Although the .NET Framework has grown release after release, the core principles have remained the same, and a good part of the evolution is to be found at the level of additional application programming interfaces (APIs) that are made available through the class libraries. A similar observation of evolution obviously holds on the level of the managed languages: Features are added every time around that often require additional framework support (for example, Language Integrated Query [LINQ] in C# 3.0, dynamic in version 4). As you can imagine, keeping track of all those versions and their key differentiating features isn’t always easy. To make things more clear, take a look at Table 3.1.

Table 3.1. .NET Platform Version History

Version

Codename

Visual Studio

C#

VB

Flagship Features

1.0

Lightning

2002 (7.0)

1.0

7.0

Managed code

1.1

Everett

2003 (7.1)

1.0

7.0

2.0

Whidbey

2005 (8.0)

2.0

8.0

Generics

3.0

WinFX

2005 (8.0)

2.0

8.0

WPF, WCF, WF

3.5

Orcas

2008 (9.0)

3.0

9.0

LINQ

4.0

Dev10

2010 (10.0)

4.0

10.0

Dynamic

4.5

Dev11

2012 (11.0)

5.0

11.0

Asynchronous programming

Notice that new releases of the .NET Framework typically go hand in hand with updates to the Visual Studio tooling support. A notable exception to this rule was the .NET 3.0 release, where Visual Studio 2005 additions were made to support the newly added features (for example, by providing designer support for Windows Presentation Foundation [WPF]). Notice, however, how the managed languages evolve at a slightly slower pace. It’s perfectly imaginable that a future release of the .NET Framework will still be using C# 5.0 and VB.NET 11.0. History will tell.

NOTE: What About Operating System Integration?

Being a logical extension to the Win32 API for Windows programming, it very much makes sense to have the framework components readily available together with various versions of the Windows operating system. However, Windows and the .NET Framework have been evolving at a different pace, so the innovation on the level of the .NET Framework hasn’t always been immediately available with the operating system out there at that point in time.

One first little piece of integration with the operating system happened with Windows XP, where the image loaded was made aware of the existence of managed code, to be able to load managed executables with fewer workarounds than would be required otherwise. In the Windows Server 2003 era, the 1.1 release of the .NET Framework was brought to the operating system so that the ASP.NET web stack was available out of the box for use in web server installations.

The bigger integration story happened around Vista, driven by the WinFX vision of enhancing core system capabilities like windowing (with WPF) and communication (with WCF). For a long time during the development of Vista—known as Longhorn at the time—WinFX formed a core pillar of the next-generation operating system, and development proceeded hand in hand with the operating system. Only later was WinFX decoupled from Vista and ported back to other platforms, resulting in what became known as .NET Framework 3.0. This said, the .NET Framework 3.0 components still shipped with Windows Vista as an optional Windows component that can be turned on or off. The same holds for Windows Server 2008.

With the release of Windows 7, this tradition continued by making the .NET Framework 3.5 components available out of the box. More recently, with Windows 8, the .NET Framework 4.5 shipped out of the box with the product. But there’s more. Thanks to the tight integration with Windows Runtime, we can now truly speak of a better together story where the power of Windows is readily accessible for .NET developers.

What Table 3.1 doesn’t show is the versioning of the Common Language Runtime (CLR). There’s a very important point to be made about this: The CLR evolves at a much slower pace than the libraries and languages built on top of it. Slow most often has a pejorative feel to it, but for the CLR this is a good thing: The less churn made to the core of runtime, the more guarantees can be made about compatibility of existing code across different versions of the .NET Framework. Figure 3.1 illustrates this nicely based on the .NET Framework 3.x history.

From this figure, you can see how both .NET Framework 3.0 and .NET Framework 3.5 are built to run on top of the existing CLR 2.0 runtime bits. This means that for all the goodness that ships with those versions of the .NET Framework, no changes were required to the core execution engine, a good sign of having a solid runtime that’s ready to take on a big job.

NOTE: Red Bits Versus Green Bits

A concept you might sometimes hear from Microsoft people in the context of framework versioning is that of red bits and green bits. The categorization of framework assemblies in red bits and green bits was introduced in the .NET 3.x timeframe to distinguish between new assemblies (green bits) and modifications to existing ones (red bits). Although .NET 3.x mostly added new library functionality to the existing .NET 2.0 layer, some updates were required to assemblies that had already shipped. With the distinction between red bits and green bits, development teams kept track of those modifications also to minimize the changes required to red bits to reduce the risk of breaking existing applications.

What all this means in practice is that .NET 3.0 is a superset of .NET 2.0, but with some updates to the .NET 2.0 binaries, in the form of a service pack. Those service packs are also made available by themselves because they contain very valuable fixes and optimizations, and they are designed to be fully backward compatible so as not to break existing code. Windows Update automatically deploys these service packs to machines that already have the framework installed.

NOTE: Lost in Translation

Even more remarkable than the capability to add gigantic libraries like WPF and Windows Communication Foundation (WCF) on an already existing runtime without requiring modifications to it is the fact that very powerful language extensions have been made in .NET 3.5 with the introduction of LINQ. However, none of those new language additions required changes to the runtime or intermediate language (IL). Therefore, C# 3.0 and VB 9.0 programs can run on the .NET 2.0 CLR. Even more, it’s theoretically possible to cross-compile C# 3.0 programs into C# 2.0 code with an equivalent meaning. A paper proving this claim was written by a group of language designers at Microsoft and is titled “Lost in Translation.”

One caveat, though: Don’t take this to mean that C# 3.0 programs can be ported blindly to .NET 2.0 because implementations of various LINQ providers ship in various .NET 3.5 assemblies.

Another advantage that comes from keeping the runtime the same across a set of framework releases is the capability to reuse existing tooling infrastructure (for example, for debugging). With the release of Visual Studio 2008, this capability became visible to .NET developers under the form of multitargeting support. What this feature enables is to use Visual Studio 2008 to target .NET Framework 2.0, 3.0, and 3.5 using the same comfortable tooling environment. And with .NET 4.0 and .NET 4.5—as you’ll see later in this chapter when we explore Visual Studio 2012—multitargeting has been extended to support all releases from .NET 2.0 to 4.5.

What about .NET Framework 1.x? Development targeting those platforms will always be tied to the use of the releases of Visual Studio that shipped with it (that is, Visual Studio .NET versions 2002 and 2003). Too many fundamental changes to runtime infrastructure were made between versions 1.x and 2.0 of the CLR, making multitargeting support for .NET 1.x unfeasible. Luckily nowadays, the use of .NET 1.x has largely been phased out. If you still have .NET 1.x applications around, now is the time to port them to a more recent version of the platform (preferably .NET 4.0, of course).

But why should someone care to target an older release of the .NET Framework? Most commonly, the answer is to be found in deployment constraints within companies, web hosting providers, and so on. Having tooling support to facilitate this multitargeting is pure goodness and also means you can benefit from core enhancements to the Visual Studio tools while targeting older releases of the .NET Framework.

.NET Framework 4.5

The particular version of the .NET Framework we target in this book is .NET 4.5, using Visual Studio 2012 and C# 5.0. Other than the .NET 3.x releases, .NET 4.x has a new version of the CLR underneath it, and obviously—in the grand tradition—it comes with a bunch of new class libraries that will make life easier for developers.

Two key features about .NET 4.x are important to point out here:

Side-by-side support: This means that .NET 4.x can be installed next to existing versions of the .NET Framework. What’s so special about this compared to .NET 3.x? The key difference is updates to existing class library assemblies are no longer carried out in-place, but new versions are put next to the existing ones.

Backward compatibility: This provides tremendous value to developers, allowing reuse of existing code and components. In practice, it means that existing code that was compiled against .NET 2.0 or 3.x in the past can now be targeted at .NET 4.x without requiring source-level code changes.

Figure 3.2 illustrates a machine with all the versions of the .NET Framework installed next to one another.

The full version numbers of the CLR and .NET Framework installations and binaries can be somewhat distracting at first sight. Where do they come from?

In the .NET Framework 1.x timeframe, the build number (the third component of the version number) was simply created incrementally. Version 1.0 released at build 3705, and version 1.1 ended up at build 4322.

With .NET 2.0, it made sense to give more meaning to the build number, and the pattern ymmdd was chosen: one digit for the year (2005), two digits for the month (July), and two for the day (27).

This approach worked very nicely until the theoretical 35th day of the 55th month of the year 2006: The metadata encoding for build numbers cannot exceed 65535, so we’re out of luck using this pattern in its full glory. The result was a compromise. The month and year encodings are kept the same, but the year is now considered relative to the start of the release. For the .NET 4.0 release, the start of the release was in 2007, so from Figure 3.2, one can infer that .NET 4.0 was built on March 19, 2012. Because the .NET 4.5 release is an in-place update, the folder name has stayed the same, even though the revision number of the files in the folder has gone up.

Besides having various versions of the .NET Framework, .NET 4.0 pioneered the availability of different “flavors.” Around the .NET 3.5 timeframe it became apparent that the size of the .NET Framework had grown too large to enable fast friction-free installs, which are especially important for client application deployments. Significant factors for such deployments are download times and installation times.

To streamline typical deployments of the framework, a split of the .NET Framework class libraries was made, factoring out so-called Client Profile assemblies. The Client Profile bubble contained the Base Class Library (BCL) and libraries required to write client applications using WPF and WCF. The remaining part (referred to as Extended Profile) was layered on top of the Client Profile subset and contained features like ASP.NET that client applications typically don’t need. As a result, the deployment and installation footprint of the Client Profile is kept small, while it’s still possible to upgrade such an installation to the full framework. Figure 3.3 shows the layered cake architecture of those profiles in the .NET 4.0 timeframe.

Together with this split, Visual Studio 2010 extended its notion of multitargeting to the various “profiles” of the .NET Framework. By doing so, developers didn’t have to memorize which libraries are available in each profile. When the Client Profile subset is selected, Visual Studio prevents assemblies from the Full framework from being referenced.

During the .NET 4.5 timeframe, a big investment was made to reduce download and installation sizes and to decrease the installation time. As a result, the split of a Client Profile and Extended Profile was no longer necessary, resulting in the discontinuation of the Client Profile package.

.NET 4.5 introduces a new notion of profiles though, through the new Portable Library support. When writing portable class libraries, you can select the target platforms the library can run on. For example, you could build a portable library targeting .NET Framework 4.5, .NET for Windows Store applications, and Windows Phone 8. The resulting project will have access only to the .NET Framework functionality available in the intersection for those platforms, hence ensuring the resulting assembly works on all of the selected platforms. In the past, developers had to maintain separate builds of their libraries for each target platform, causing major grief. Portable Library aims to take away this pain.

To make the intersection of APIs across different target platforms as stable as possible, the bottommost layer of the framework was split off in a “.NET Core” set of assemblies. This foundation is what future releases of the framework are based on, and is used by .NET 4.5 on the desktop, .NET for Windows Store applications, and Windows Phone 8. When you are targeting older platforms, such as Silverlight or .NET 4.0, the set of APIs available in the intersection will differ because of prior differences between different flavors of the .NET Framework. With the .NET Core and Portable Library refactoring in place, the fragmentation of the framework libraries should be reduced substantially.

Running the Installer

Playtime! To write code on the .NET Framework 4.5, let’s start by installing the Full .NET Framework package. That’s really all you need to get started with managed code development.

Where to get it? Browse to http://msdn.com/netframework and click the link to the .NET Framework 4.5 download. The installer itself should be straightforward to run: Accept the license agreement, get a cup of coffee, and you’re ready to go. On Windows 8, you can use the Turn Windows Features On or Off Control Panel applet to enable or disable the .NET Framework 4.5 feature. Figure 3.4 shows the default feature selection on a clean Windows 8 installation.

What Got Installed?

When the installation is complete, it’s good to take a quick look at what was installed to familiarize yourself with where to find stuff.

The Runtime Shim

The runtime shim is really something you shouldn’t care much about, but it’s a convenient way to find out the latest version of the installed CLR on the machine. The purpose of the shim is to load the correct version of the CLR to execute a given application, a particularly important task if multiple versions of the runtime are installed.

You can find the shim under %windir%\system32, with the name mscoree.dll. By looking at the file properties (shown in Figure 3.5), you’ll find out about the latest common language runtime version on the machine.

Figure 3.5. The version of the CLR runtime shim.

Although the file description states “Microsoft .NET Runtime Execution Engine,” this is not the CLR itself, so where does the runtime itself live?

The .NET 4.0 CLR

Having a runtime shim is one thing; having the runtime itself is invaluable. All runtime installations live side by side in the %windir%\Microsoft.NET\Framework folder. On 64-bit systems, there’s a parallel Framework64 folder structure. Having two “bitnesses” of the CLR and accompanying libraries is required to allow applications to run either as 32-bit (Windows On Windows, or WOW) or 64-bit.

Starting with .NET 4.0, the CLR itself is called clr.dll (previously, mscorwks.dll), as shown in Figure 3.6. The same CLR is used for .NET 4.5, so we’ll refer to it using the 4.0 version number.

The Global Assembly Cache

The Global Assembly Cache (GAC) is where class library assemblies are loaded for use in .NET applications. You can view the GAC under %windir%\assembly, but a command-line directory listing reveals the structure of the GAC in more detail. We discuss the role of the GAC and the impact on your own applications exhaustively in Chapter 25, “Assemblies and Application Domains.”

Figure 3.7 shows the structure of the .NET 4.0 GAC containing the 4.0 version of the System.dll assembly, one of the most commonly used assemblies in the world of managed code development.

Notice the v4.0 prefix in the name of the folder containing the .NET 4.0 version of System.dll? This is an artifact of the “GAC splitting” carried out in .NET 4.0. This simple naming trick hides assemblies targeting different versions of the runtime so that a specific version of the CLR doesn’t try to load an assembly that’s incompatible with it. In the preceding example, CLR 2.0 will recognize only the first folder as a valid entry in the GAC, whereas CLR 4.0 recognizes only the second one. This truly shows the side-by-side nature of the different runtimes.

Tools

Besides the runtime and class library, a set of tools get installed to the framework-specific %windir%\Microsoft.NET\Framework folder. Although you’ll only use a fraction of those on a regular basis—also because most of those are indirectly used through the Visual Studio 2012 graphical user interface (GUI)—it’s always good to know which tools you have within reach. My favorite tool is, without doubt, the C# compiler, csc.exe. Figure 3.8 shows some of the tools that ship with the .NET Framework installation.