#487 – Build Configurations Allow Saving Sets of Project Properties

In Visual Studio, a build configuration represents a set of saved properties that affect the build process.

A build configuration can be associated with a solution or with individual projects.

A build configuration at the solution level dictates which projects to build for that configuration, which build configurations to use for individual projects, and which platform to build each project for.

At the project level, a build configuration allows setting different project properties for each configuration.  For example, a “Debug” configuration might be configured to define the DEBUG constant and generate full symbols for debugging purposes.

You select the current build configuration to use by selecting an item from the Solution Configurations dropdown in the main toolbar.

You can also select Configuration Manager from the Build menu and then change the configuration in the Active solution configuration dropdown.

#486 – Unnecessary Project References Are Ignored

When we wanted to use the Dog type, which was defined in a DogLibrary assembly, we added a reference to DogLibrary from the project that wanted to use the type.

We then saw that the manifest of DogApplication indicated that DogLibrary was a dependent assembly.

But notice all of the other references that show up in Visual Studio, none of which are seen in the manifest as dependencies.

When you build your project, the build system only created dependencies for referenced projects that your application actually uses.  If we change the code to comment out use of the Dog type, but instead use a Uri type, we’ll get the following manifest:

The manifest now includes a dependency on the System assembly, because that’s where the Uri type is defined.

#485 – Project References and Dependent Assemblies

In Visual Studio, you add project references to indicate that you want to use types from another assembly.  For example, a main application (e.g. DogApplication.exe) might reference a class library (e.g. DogLibrary.dll) containing types that it wants to use.  These references allow the compiler to make sure that you are using the dependent types correctly, based on the metadata contained in the referenced assembly.

When you build a project, information represented by project references is converted to assembly dependency information, stored in the manifest of the assembly that you are generating.

An assembly’s manifest contains information about all of the other assemblies that the assembly depends on.  You use the IL Disassembler to look at an assembly’s manifest.

Double-click to open the manifest and you’ll see that DogLibrary is listed as a dependent assembly–an assembly that the DogApplication assembly depends on in order to run.

#484 – Add a Project Reference to Use a Type from Another Project

Let’s say that you’re authoring two different projects in Visual Studio–one that will contain a type (like Dog) and one that will use that type.  You need to set up a project reference so that the project that wants to use the Dog class knows about the project that defines Dog.

Assume that the project containing the Dog class will be a class library (.dll) that we’ll call DogLibrary.  We’ll also generate a console application project (.exe) that uses the Dog  class, which we’ll call DogApplication.

To use the Dog class from the console application, we need to set up a project reference so that DogApplication knows about DogLibrary.  Right-click on DogApplication and select Add Reference…

On the Projects tab, which lists other projects in this solution, select DogLibrary and click OK.

In the References folder for DogApplication,  you’ll now see that this project references the DogLibrary project.

#483 – Adding a new Project to an Existing Solution

A solution in Visual Studio can contain one or more projects.  When you create a new solution using the New Project wizard, you typically get a solution with a single project.

You can add additional projects to a solution at any time, representing additional components that will be built when you build all source code in the solution.

As an example, suppose that you use the New Project wizard to create a WPF Application called MyWPFApp.  You’ll get a solution with a single project.

Now let’s say that you want to add a class library (DLL) to your project.  You right-click on the solution in the Solution Explorer and select Add | New Project.

You’ll get the Add New Project dialog, where you can select Class Library as the project type, give the project a name, and press OK.

You’ll now see the new project in the Solution Explorer.

#482 – Basic Project Types in Visual Studio

The first step in creating a new application is typically to use the New Project wizard in Visual Studio.  The wizard creates a new solution with one or more projects containing a minimum set of source code files that represent a project of the desired type.

The more common project types that you might create include:

  • A WPF (Windows Presentation Foundation) client application

  • A WPF Ribbon application – a WPF client with a Ribbon control

  • A Console application – an application that sends all output to a console window

  • A class library – a DLL that contains .NET types that an application might make use of

  • A WPF Browser application – a WPF app that can be deployable from a browser

  • A Windows service – an application that runs in the background as a Windows service

  • A WPF custom control library – A DLL containing one or more custom controls deriving from Control

#481 – Projects and Solutions in Visual Studio

When you work with Visual Studio to develop an application, you organize your source code into projects and solutions.

Projects contain items such as your source code files and typically are configured to produce a single deployable object at build time, like a Console Application (.exe), WPF Application (.exe) or a Class Library (.dll).  A project is something that you can build individually, generating the desired output (like an .exe or .dll file).

Solutions act as containers for projects.  You can perform certain operations, like building the software, for the entire solution.

When you open Visual Studio, you typically open a solution.  You then use the Solution Explorer to view and manage items contained in projects within that solution.

The example below shows a solution (ConsoleApplication1) that contains two projects–a Console Application packaged as an .exe file (ConsoleApplication1) and a class library packaged as a .dll file (DogLibrary).

#480 – Pre-Processing Directives

Pre-processing directives are elements that you can include in your source code that are not part of the source code itself.  Instead, they instruct the C# compiler to perform some particular action, like skipping compilation of a section of the code.

The pre-processing directives available in C# include:

  • #define/#undef – Define/undefine condition compilation symbols (see #if)
  • #if/#elif/#else/#endif – Skip compilation of a section of code based on the existence of a conditional compilation symbol
  • #line – specifies a line number to use when reporting errors
  • #error – issue errors during compilation
  • #warning – issue warnings during compilation
  • #region/#endregion – define a collapsible code region, to improve readability
  • #pragma warning – disable or restore certain compiler warnings
  • #pragma checksum – generate a checksum for an ASP.NET page, for debugging purposes

#479 – Identical String Literals Are Stored in the Same Object

The C# compiler will store equivalent string literals in the same underlying System.String object.

In the example below, s1 and s2 refer to the same string literal, so they will share the same underlying System.String object.  s3 will get the same string value assigned to it at runtime, but will be stored in a different object.

            string s1 = "Popeye";    // s1 & s2 will refer to the same
            string s2 = "Popeye";    //   underlying object

            // Enter "Popeye" for s3.  It will be stored in a
            //   different object, though equivalent to s1 & s2.
            string s3 = Console.ReadLine();

            object o1 = s1;
            object o2 = s2;
            object o3 = s3;

            bool bEqual = (o1 == o2);    // True, same object
            bEqual = (o1 == o3);         // False, different objects

We don’t normally care about whether two equivalent strings are stored in the same or different objects, because the == operator for System.String always checks for string equivalence, rather than object identity.

#478 – Verbatim String Literals Can Span Multiple Lines

A verbatim string literal is one in which no escape sequences are processed.  The string contains exactly the characters entered.  Verbatim strings can also span multiple lines.

            string multilineGuy1 = @"This
string with embedded \t escape sequences";

In fact, you can only include a multiline string in your source code if it’s declared as a verbatim string.

            string multilineGuy1 = "Let me not to the marriage of true minds
Admit impediments. Love is not love";

            string multilineGuy1 = @"Let me not to the marriage of true minds
Admit impediments. Love is not love
Which alters when it alteration finds,";