Inside Visual Studio 2008

Visual Studio is Microsoft's flagship for developers, and Visual Studio 2008 is the first version of Visual Studio to support multiple versions of .NET.


January 10, 2008
URL:http://www.drdobbs.com/tools/inside-visual-studio-2008/205602188

Dino writes the ASP.NET-2-The-Max newsletter for DDJ. He can be contacted at weblogs.asp.net/despos/.


Since the release of the .NET Framework 1.0, Microsoft has committed to a made-to-measure programming environment with each new version of its managed framework. But for a number of reasons, this tradition was interrupted last year when .NET Framework 3.0 made its debut without a new version of Visual Studio. This year, however, .NET 3.5 comes out with a new programming environment—Visual Studio 2008.

Visual Studio is designed as a container environment that integrates the functionality of multiple visual designers for just about any supported type of application and component. This means you have ready-made templates for a variety of Windows and web application types, including Windows Forms, Windows Presentation Foundation (WPF), ASP.NET sites, and web services. In addition, Visual Studio 2008 offers ad hoc designers for creating workflows and Windows Communication Foundation (WCF) services. The characteristics of each output component are managed through projects, and in turn grouped in solution containers.

The true added value of Visual Studio—and perhaps the primary reason to consider upgrades—is the boost it gives to developer productivity. Dozens of wizards, smart and context-sensitive popup windows, effective debuggers, and visual designers are examples of facilities that may not necessarily make any code automatically smarter, but still help you focus on key points—skimming over chores, repetitive tasks, and overzealous procedures.

Multitarget Projects

Have you noticed that previous releases of Visual Studio only supported one version of the .NET Framework? For years, my desktop was swarming with shortcuts to different versions of Visual Studio based on the projects I maintained at the time: Visual Studio 2002 for .NET Framework 1.0 applications, Visual Studio 2003 for .NET Framework 1.1, and Visual Studio 2005 for .NET Framework 2.0 applications. Finally, Visual Studio 2008 introduces a cool feature called "multitargeting" that lets us create applications for specific versions of the .NET Framework.

Multitargeting brings two main benefits to the table:

Multitargeting in Visual Studio 2008 starts with .NET 2.0 (Figure 1) and should continue for most of the foreseeable future versions. Significant changes in the Common Language Runtime (CLR) that occurred between .NET 1.1 and 2.0 made it impossible to extend multitargeting to just any existing versions of the Framework. The nice thing about multitargeting is that any piece of the Visual Studio 2008 UI adapts to the target platform. The toolbox of controls, compiler settings, the list of assemblies to reference, IntelliSense on objects, and, of course, binaries are all specific to the selected platform.

[Click image to view at full size]

Figure 1: Choosing a target platform for a Visual Studio 2008 project.

The target platform is not a definitive choice. At any moment, you can upgrade or downgrade to any of the supported targets. You do this from the property pages of the project in the Solution Explorer (Figure 2).

[Click image to view at full size]

Figure 2: Upgrade the target .NET of an existing project.

Should you install Visual Studio 2008 if you're mostly maintaining existing .NET Framework 2.0 applications? Clearly, the big news about Visual Studio 2008 is the support it offers for 3.x .NET applications. However, even from a platform-agnostic perspective, there's something it offers—an improved set of facilities with a particular attention to web developers. JavaScript debugger, CSS, master pages designer, and LINQ helper tools are all features available independently from the target platform.

Some C# and VB Syntactic Sugar

In Visual Studio 2008, C# and Visual Basic offer a few time-saving features that basically give the compiler the burden of creating some required code. In the end, these features are just syntactic sugar that make C# and VB programming easier and more pleasant.

"Automatic properties" is a feature that instructs the compiler to automatically add a default implementation for the getter/setter methods of a class property. This code is now perfectly legal in a class compiled with the newest C# compiler:


public string ContactName { get; set;}

The compiler automatically expands this code like this:


private string contactName;
public string ContactName
{
   get { return contactName; }
   set { contactName = value; }
}


Automatically generated get/set properties are not equivalent to public fields. From a metadata perspective, properties and fields are quite different entities. The idea here is that you just delegate to the compiler the creation of some plumbing code, in the most common and simple scenario. At a later time, you can always come back and provide your own getter/setter methods.

Object initializers are another piece of syntactic sugar to speed up the creation of the code that initializes an object. Instead of going through a potentially long list of assignment instructions, you can code it like this:


Person person = new Person { 
    FirstName="Dino", 
    LastName="Esposito", 
    Age=24 
};

The idea is extended to collections, as in this code:


List<Person> friends = new List<Person> {
   new Person { FirstName="Nancy", LastName="Davolio", Age=28 },
   new Person { FirstName="Andrew", LastName="Fuller", Age=35 },
   :
};


Compared to the syntax required in Visual Studio 2005, the savings is pretty clear and can easily sum up to tens of lines of code for large procedures.

Richer Languages Beyond the Sugar

Programming languages are not immutable. Especially when they're tightly coupled to a runtime environment such as the CLR, they progress as the underlying machinery is refined and enhanced. For example, the .NET Framework 2.0 supplied a C# compiler with additional features compared to the compiler for the .NET Framework 1.x. In Visual Studio 2008 and with .NET 3.5 onboard, you can use a significantly richer C# and Visual Basic .NET languages.

Both languages now incorporate features that enable functional programming and add specific keywords for Language Integrated Queries (LINQ).

Extension methods are a way to extend the otherwise hard-coded contract of a class by adding new methods programmatically without creating a derived or partial class. The idea behind extension methods is bringing the flexibility of duck-typing to a strongly-typed and compiled environment such as the CLR. In practice, you may use extension methods whenever you feel that a given class you're using lacks a helpful method. If you have no access to the source code of this class, in Visual Studio 2008 you define an extension. Extension methods can be defined for any class, including native classes of .NET. Listing One shows how to extend the System.String class with a few methods such as IsDate, IsInt32, and ToDate.

namespace Samples
{
    public static class StringExtensions
    {
        public static bool IsInt32(this string content)
        {
            int number;
            bool result = Int32.TryParse(content, out number);
            return result;
        }
        public static bool IsDate(this string content)
        {
            DateTime date;
            bool result = DateTime.TryParse(content, out date);
            return result;
        }
        public static DateTime ToDate(this string content)
        {
            DateTime date;
            bool result = DateTime.TryParse(content, out date);
            if (result)
                return date;
            else
                return DateTime.MinValue;
        }
        public static int ToInt32(this string content)
        {
            int number;
            bool result = Int32.TryParse(content, out number);
            if (result)
                return number;
            else
                return Int32.MinValue;
        }
    }
}
Listing One

An extension method is defined as a static method on a static class. The binding between the method (say, IsInt32) and type (say, System.String) is established through the this keyword in the method's prototype:

     
public static bool IsInt32 (this string content)


The type that follows the this keyword is treated as the type to extend. Figure 3 shows IntelliSense in action on the extended System.String type.

[Click image to view at full size]

Figure 3: IntelliSense shows dynamic extensions to the String type.

The following code illustrates how you can use these new methods in your code:


void btnDate_Click(object sender, EventArgs e) {
  string content = textBox1.Text;
  if (content.IsDate()) {
    DateTime date = content.ToDate();
    label2.Text = String.Format("Next day is {0}", 
       date.AddDays(1).ToString("dd MMMM yyyy"));
  }
  else
      label2.Text = "Not a valid date.";
} 


Extension methods are checked at compile-time and can be applied also to any parent class or interface in .NET. (Extension methods could be used to obtain a feature that looks similar to mix-ins. Overall, a mix-in is a sort of interface with implemented methods. A class that implements a mix-in includes—but not inherits—all the members on the mix-in's interface. Currently, C# and Visual Basic .NET don't natively support mix-ins, even though instructing the compilers to produce the code for it didn't appear to be a huge effort. With extension methods, you can simulate mix-ins in the latest C# and Visual Basic .NET.)

The var keyword is another interesting new entry. Used to qualify a variable, it doesn't indicate a late-bound reference. Instead, it merely indicates that you don't know the type of the variable at the time of writing. However, the type won't be determined at runtime (late-binding), but the compiler infers the type from the expression assigned to the var variable. For this reason, an initial value assignment is required to avoid a compiler error. When var is used, a strongly typed reference is always generated.

The var keyword enables another cool C# feature—the anonymous type. This is an unnamed type that you define using the same object initializer syntax mentioned earlier:


var person = new { 
    FirstName="Nancy",
    LastName="Davolio", 
    Age=28
};


For the CLR, anonymous and named types are exactly the same entity. Anonymous types can be used in a variety of scenarios, but have been introduced primarily to support LINQ queries.

The same can be said for lambda expressions. Lambda expressions are used as a convenient way to create delegates, especially (but not uniquely) in LINQ. In .NET, a delegate is an object-oriented wrapper for a function pointer and points to an existing and named function in a class. In .NET 2.0, managed languages offered new, powerful construct—anonymous methods. Basically, you have an explicit code snippet defined inline and used as an unnamed method of some class. Lambda expressions are a further refinement of the idea of an anonymous method, just less verbose and niftier.

LINQ Facilities

Most Windows and web applications are centered on some sort of data repository, usually a relational database. To retrieve data, you have to use a different API each time. It can be SQL for relational databases, XQuery and XPath for XML documents, some interface (ICollection, for instance) for collections and arrays. The main goal of LINQ is unifying this model by providing an ad hoc framework. Conveniently, this query framework is wired to some new keywords in C# and VB:


int[] fiboNumbers = new int[] {0,1,1,2,3,5,8,13,21,34};
var data = from n in fiboNumbers
           where n % 2 == 0
           select n;


As weird as it may seem, this is C# code that compiles in Visual Studio 2008. The new keywords are from, where, and select. Their meaning is really close to the meaning that analogous keywords have in SQL. Translated to human language, the query assigns to the data variable all elements in the queryable object (a collection, in this case) that match the specified condition (all even numbers in this case). Here's another LINQ expression that uses lambdas:


var data = (from c in customers
            where c.Country == "USA"
            select c).SelectMany(c => c.Orders);


A lambda expression is characterized by the => operator, prefixed by input parameters, and followed by the parametric expression to evaluate. The preceding code selects all U.S. customers and flattens the result set to a list of orders. Without the SelectMany keyword and the input lambda, you'll get an array of collections of orders—not a list of order objects.

LINQ operators work on objects that implement a particular interface—IQueryable. .NET 3.5 counts a number of these objects. They are wrappers for well-known data containers such as collections, XML documents, DataSets, and SQL Server databases. The model is extensible too, so third-parties can provide their own LINQ engine to query Oracle databases or perhaps the filesystem.

The most interesting of LINQ queryable objects is the object that wraps a SQL Server 200x database. It is a user-defined class that inherits from a base class named DataContext. Visual Studio 2008 provides an ad hoc visual tool called "O/R designer"; see Figure 4. After you set up a database connection in the Server Explorer window, you drop tables and stored procedures in the designer and get a dynamically generated class to work with. Next, you simply instantiate this class and use it as the queryable object:


NorthwindDataContext dataContext = 
     new NorthwindDataContext();
var data = from c in dataContext.Customers
     where c.Country == "Spain" 
     select c;


[Click image to view at full size]

Figure 4: O/R designer modeling the SQL Server's Northwind database.

You can then go through the returned result set using a for/each statement or just bind the object to a data-bound control.

Visual Studio 2008 Projects

LINQ facilities span over all types of projects where database access and queries make sense. But other improvements are specific to web projects. For example, the editor of master pages has been enhanced to fully support nested master pages. Nested master pages were already working in ASP.NET 2.0, but were not fully backed by the visual designer of Visual Studio 2005. In addition, Visual Studio 2008 delivers support for split-view editing and a new CSS designer. A JavaScript debugger and IntelliSense extended to JavaScript classes complete the offering for web developers. From the framework perspective, the .NET Framework 3.5 has built-in support for AJAX that goes a little beyond what was already released as ASP.NET AJAX Extensions 1.0 for ASP.NET 2.0. In addition to features such as UpdatePanel and ScriptManager, you find AJAX-enabled Web Parts, WCF support for JSON, plus bug fixes and performance improvements.

On the Windows side, in Visual Studio 2008 you finally have a true WPF designer with a toolbox and a classic Properties box. Figure 5 previews the feature.

[Click image to view at full size]

Figure 5: WPF designer in Visual Studio 2008.

Visual Studio 2008 also has flavors specifically created to facilitate tests and full application management, such as Visual Studio 2008 Team Suite and Visual Studio 2008 Team Foundation Server. The good news is that unit testing support is not just faster, but is included in the Professional edition of Visual Studio 2008.

WCF and Workflow Support

Version 3.0 was the first version of .NET to ship without a dedicated version of Visual Studio. Microsoft released a few extensions to Visual Studio to make it easier for developers to build WCF services and workflows, but in fact it just separates downloads. WCF and workflow projects and related renewed designers are included in Visual Studio 2008. Figure 6 shows the workflow designer whose toolbox distinguishes between version 3.0 and 3.5 activities. The newest activities include an activity to send and receive JSON data to and from a WCF service.

[Click image to view at full size]

Figure 6: Workflow designer in Visual Studio 2008.

Conclusion

Visual Studio is Microsoft's flagship for developers, and Visual Studio 2008 is the first version of Visual Studio to support multiple version of .NET. You can choose the target platform when you create the project and find around you an IDE that offers only controls and components adequate to the target platform. The improved capabilities of editors and designers, though, are shared by all projects, regardless of the platform. Visual Studio 2008 fully integrates in the IDE tools for creating workflows as well as WCF and WPF assemblies. It also brings in AJAX capabilities in ASP.NET web projects and adds JavaScript to the list of languages for which it can offer serious debugging and IntelliSense features. Available in a variety of formats such as Standard, Professional, and Team Suite, it is also available in free Express versions.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.