A Sneak Preview of Visual C# Whidbey
Microsoft Corporation
November 2003
Contents
Introduction
Language Innovation
Compiler Enhancements
Productivity Enhancements
Debugger Enhancements
Summary
Note This document was developed prior to the product's release to manufacturing, and as such, we
cannot guarantee that any details included herein will be exactly the same as those found in the shipping
product. The information represents the product at the time this document was published and should be
used for planning purposes only. Information is subject to change at any time without prior notice.
Introduction
The next release of Microsoft Visual Studio®, codenamed "Whidbey," has been significantly improved for
C# developers by adding innovative language constructs, new compiler features, dramatically enhanced
developer productivity, and an improved debugging experience. In the area of language innovation, the
Whidbey release of C# will support generics, iterators, partial types, and anonymous methods. New
compiler features for Whidbey enable developers to do things like disable compiler warnings directly in
code or verify ECMA/ISO conformance. Whidbey will also include several productivity enhancements
include refactoring, code expansions, code formatting, enhanced IntelliSense, and much more. The
debugging experience has also been improved with new features like enhanced datatips, debugger
visualizers, design-time expression evaluation, and more. This document is a sampling of some of the
new capabilities available in Whidbey and we are continuing to add new features that customers want.
Language Innovation
Generics
Generics are one of the big language additions to the C# language in Whidbey. Generics in C# allows
classes, structs, interfaces, and methods to be parameterized by the types of data they store and
manipulate. Generics are useful because many common classes and structs can be parameterized by the
types of data being stored and manipulated. These are called generic class declarations and generic
struct declarations. Similarly, many interfaces define contracts that can be parameterized by the types of
data they handle. These are called generic interface declarations. Methods may also be parameterized by
type in order to implement generic algorithms, and these are known as generic methods.
In the example below, we create a Stack generic class declaration where we specify a type parameter,
called ItemType, declared in angle brackets after the declaration. Rather than forcing conversions to
and from object, instances of the generic Stack class will accept the type for which they are created
and store data of that type without conversion. The type parameter ItemType acts as a placeholder
until an actual type is specified at use. Note that ItemType is used as the element type for the internal
items array, the type for the parameter to the Push method, and the return type for the Pop method:
public class Stack
1<itemtype>
2{
3private ItemType[ ] items;
4public void Push(ItemType data) {...}
5public ItemType Pop() {...}
6}
7When we use the generic class declaration Stack, as in the short example below, we can specify the
8actual type to be used by the generic class. In this case, we instruct the Stack to use an int type by
9specifying it as a type argument using the angle notation after the name:
10Stack<int> stack = new Stack<int>();
11stack.Push(3);
12int x = stack.Pop();
13In so doing, we have created a new constructed type, Stack<int>, for which every ItemType
14inside the declaration of Stack is replaced with the supplied type argument int. Indeed, when we
15create our new instance of Stack<int>, the native storage of the items array is now an int[] rather
16than object[], providing substantial storage efficiency. Additionally, we have eliminated the need to
17box the int when pushing it onto the stack. Further, when we pop an item off the stack, we no longer
18need to explicitly cast it to the appropriate type because this particular kind of Stack class natively
19stores an int in its data structure.
20If we wanted to store items other than an int into a Stack, we would have to create a different
21constructed type from Stack, specifying a new type argument. Suppose we had a simple Customer
22type and we wanted to use a Stack to store it. To do so, we simply use the Customer class as the type
23argument to Stack and easily reuse our code:
24Stack<customer> stack = new Stack<customer>();
25stack.Push(new Customer());
26Customer c = stack.Pop();
27Of course, once we've created a Stack with a Customer type as its type argument, we are now limited
28to storing only Customer objects (or objects of a class derived from Customer). Generics provide
29strong typing, meaning we can no longer improperly store an integer into the stack, like so:
30Stack<customer> stack = new Stack<customer>();
31stack.Push(new Customer());
32stack.Push(3); // compile-time error
33Customer c = stack.Pop(); // no cast required
34Partial Types
35Partial types allow a single type, like a class, to be split into multiple files. The most useful aspect of this
36feature is for code generators like Visual Studio, which generate code into a different file from
37user-written code. In this manner, the designer can much more easily parse and regenerate its code
38without affecting the code that the user has written. For example:
39// Form1Designer.cs
40public partial class Form1: System.Windows.Forms.Form
41{
42// Designer code
43void InitializeComponent() { … }
44}
45// Form1User.cs
46public partial class Form1
47{
48// user code
49void Mouse_Click(object sender, MouseEventArgs e) { … }
50}
51Anonymous Methods
52Anonymous methods can be thought of as the ability to pass a code block as a parameter. In general,
53anonymous methods can be placed anywhere that a delegate is expected. The simplest example is
54something like:
55button1.Click += delegate { MessageBox.Show("Click"); };
56There are a few things to notice here. First, it's legal to write a method inline. Second, there is no
57description of either the return type or the method parameters. Third, the keyword delegate is used to
58offset this construct. The return type isn't listed because the compiler infers it. That is, the compiler
59knows what is expected (EventHandler), and then checks to see if the anonymous method defined is
60convertible to that method.
61You may notice that in the previous example there were no parameters listed. This is because they
62weren't needed within the code block. If these parameters were used, then the declaration would look
63like this:
64button1.Click += delegate(object sender, EventArgs e)
65{ MessageBox.Show(sender.ToString()); };
66Notice that both the type and parameter name are given.
67Iterators
68Iterators can be thought of as the logical counterpart to the foreach statement in C#, in that iterators
69simplify the process of iterating through a collection. Currently, it's very easy to iterate over collections
70using the foreach keyword. However, writing a collection that is foreach enabled requires the
71implementation of the IEnumerable and IEnumerator interfaces, as well as the creation of a separate
72Enumerator class/struct. Iterators alleviate the work of writing this boilerplate code and make it easier
73for framework developers to expose enumerable collections. For example:
74class List<t>: IEnumerable<t>
75{
76private T[] elements;
77public IEnumerator<t> GetEnumerator()
78{
79foreach (T element in elements)
80{
81yield element;
82}
83}
84}
85You'll notice above the use of the newly introduced keyword yield. yield can only be used in methods
86that return IEnumerator, IEnumerable, or their generic equivalents. Iterators can also be named and
87passed as parameters, however, in most cases named iterators will return IEnumerable instead of
88IEnumerator. For example:
89class List<t>
90{
91private T[ ] elements;
92public IEnumerable<t> Range(int from, int to)
93{
94while (from < to) yield elements[from++];
95}
96}
97Alias Qualifier (Global Namespace Qualifier)
98One of the problems that code generators face today is making sure not to interfere with any code that
99has either been written by the user, or created by a code-generation tool like Visual Studio. As a general
100practice, we encourage generators to always fully qualify the types that they emit. However, there is one
101issue with fully qualifying a type in C# in that it's not possible to search for types at the root namespace.
102The global namespace qualifier solves this problem by introducing the "::" operator, which can be used
103as a namespace or type name prefix. This lets developers explicitly reference the root namespace within
104code, as shown below.
105namespace Acme
106{
107namespace System
108{
109class Example
110{
111static void Main()
112{
113// In Visual Studio 2003, looking up
114// System.Console.WriteLine would have
115// started in the Acme.System namespace.
116::System.Console.WriteLine("Hello");
117}
118}
119}
120}
121Static Classes
122Static classes are meant to replace the design pattern of creating a sealed class with a private constructor
123that contains only static methods. A static class is denoted by placing the static modifier on the class
124declaration. For example:
125public sealed class Environment
126{
127// Keep class from being created
128private Environment() { }
129}
130can now be written as:
131public static sealed class Environment
132{
133}
134The benefit of using a static class instead of the design pattern above is that the compiler can now report
135an error if any instance methods are accidentally declared.
136Compiler Enhancements
137Inline Warning Control
138Another new feature for Whidbey is the ability to control whether warnings are reported for a particular
139region of code by specifying a compiler directive. This directive takes the familiar form of a #pragma
140statement. Below is an example that uses the pragma keyword to disable a compiler error for a
141particular block of code.
142#pragma warning disable 135
143// Disable warning CS135 in this block
144#pragma warning restore 135
145Command Line Options
146Whidbey includes several new compiler options. A short description of each of the new options follows:
147• /warnaserror: The warnaserror command line option in Visual Studio .NET 2003 enabled
148developers to treat all compiler warnings as errors. In Whidbey this feature has been extended to
149enable developers to control whether specific warnings should be treated as errors. The example
150below shows how you can mark all warnings as errors except warning 618.
151• csc /warnaserror /warnaserror-:618 ...
152Alternatively, you can mark a single warning as an error as shown in the example below:
153csc "/warnaserror:1595 ...
154• /errorreport:<string>: The errorreport command line option controls Dr. Watson reporting
155for the compiler. For more information on Dr. Watson, please visit
156http://www.microsoft.com/technet/prodtechnol/winxppro/proddocs/drwatson_setup.asp . The
157possible parameters available for the errorreport option are listed below:
158• /errorreport:prompt: This option displays a dialog box with information about the
159error.
160• /errorreport:send: This option indicates that if the compiler encounters an internal
161error it should not prompt the user with a modal dialog box. However, it should still compile and
162send the error report. The same text that would appear in the dialog box is instead written to
163the command line.
164• /errorreport:none: This option indicates that no information should be sent to
165Microsoft about the error. This is the same behavior as Visual Studio 2002 and Visual Studio
1662003, and is the default option.
167• /langversion:<string>: The langversion command line option's main purpose is to enable
168strict ECMA/ISO conformance. With this option set to ISO-1, the compiler will report errors for all
169features introduced in Whidbey that aren't part of the standard.
170• /keycontainer, /keyfile, /delaysign: These options will be used to replace the attributes of
171the same name for more flexibility in assigning command line arguments.
172Productivity Enhancements
173Refactoring
174The C# Whidbey IDE now includes refactoring support. Refactoring enables developers to automate
175many of the common tasks when restructuring code. For more information on refactoring, please visit
176http://www.refactoring.com/ . Using the built-in refactoring support, developers can, for example, use
177the rename refactoring to automate the process of renaming a variable in source code.
178The refactorings currently available in the Whidbey Technical Preview are:
179• Extract Method
180• Rename
181• Extract Interface
182• Encapsulate Field
183• Change Method Signature
184• Replace Arraylist
185The figure below shows how the refactoring features can be utilized directly from the context menu inside
186the code editor.
187Figure 1. Refactor menu
188When Rename refactoring is invoked, the user sees the Preview Changes dialog box. This dialog lists
189any places in either the comments or code where the variable name is used. The context menu in the
190Preview Changes dialog box also lets users jump directly to the line of source code referencing the
191variable.
192Figure 2. Preview Changes for the Rename refactoring
193Expansions
194Expansions, which are fill-in-the-blank" snippets of code, help reduce the number of keystrokes for
195repetitive tasks and simplify adding common constructs like the foreach statement to your application.
196Developers can access expansions by accessing the context menu and selecting expansions, or by
197directly invoking the configurable shortcut key for expansions.
198Figure 3. Expansions
199The example below shows a code expansion that uses the "forr" expansion to traverse a collection in
200reverse order. The cursor is placed on the highlighted yellow text areas, which act as placeholders for
201user values. In the example below, the "forr" expansion loops through every element in the myList
202generic collection in reverse order.
203Figure 4. forr Expansion
204Expansions are fully extensible XML files that can be customized or created by users.
205Figure 5. XML format for the "forr" expansion
206Formatting
207Source code formatting is always a matter of personal preference, and Visual Studio Whidbey includes
208several options to fully customize and control how your source code is formatted. These formatting
209options include braces, spacing, indentation, wrapping, and alignment. You also have the choice of
210having the IDE format code automatically, or just a particular section of source code. Figure 6 below
211shows the formatting new line options for braces as well as a visual preview of the selected formatting
212option.
213Figure 6. Formatting options and preview pane
214Profiles
215While developers enjoy the ability to fully customize the IDE's fonts, windows, and formatting, sharing
216your settings with other team members or transferring your settings to another machine is a difficult
217process. Whidbey adds the ability to easily import and export your IDE settings between machines or
218share them with team members.
219Figure 7. Import/Export settings dialog
220Enhanced IntelliSense
221IntelliSense has been enhanced to understand generic types. In the figure below, IntelliSense
222understands that myList represents a list of integers and provides a pop-up describing that the Add
223method of myList is expecting an integer data type.
224Figure 8. Intellisense understands generics
225IntelliSense has also been enhanced for exceptions. When adding a try/catch block, the catch handler
226intelligently filters the available options to only show a list of exception types.
227Figure 9. IntelliSense for exceptions
228IntelliSense has also been enhanced for attributes. In the example below, adding an attribute filters the
229available options to only show a list of attribute types.
230Figure 10. IntelliSense for attributes
231User Type and Keyword Coloring
232When reviewing source code, one of the easiest ways to distinguishing between types and keywords is by
233coloring them differently in the IDE. Whidbey introduces the ability to uniquely color user types and user
234keywords for easier source code readability.
235Figure 11. Different user type and keyword coloring
236New Build System
237The build system for Whidbey has been greatly improved. The new build system, named MSBuild, uses
238an extensible mechanism to describe how a build happens. Users can create their own build system using
239custom tasks written in XML. The example below shows a simple MSBuild file with a compile task that
240invokes the C# compiler for any file that ends with the ".cs" extension.
241\- <project>
242<item include="*.cs" type="Compile"></item>
243\- <target name="Build">
244<task name="Csc" sources="@(Compile)"></task>
245</target>
246</project>
247Find searches hidden text by default
248A common request we received for the Find and Replace window was to change the default behavior so
249that collapsed text, like the text inside a region, is searched by default. In Visual Studio 2003 this
250behavior is off by default, while Whidbey turns searching hidden text on by default.
251Figure 12. Searching hidden text in the find and replace dialog
252Object Browser Improvements
253While developers commonly used the object browser for inspecting data types, many wished that it
254would add the ability to filter results. The Whidbey object browser now lets developers filter and sort data
255by namespace, object type, alphabetically, and more.
256Figure 13. Object browser improvements
257Easier Window Docking
258To make docking windows easier in the IDE, we now provide you with a set of transparent guides, which
259you can hover over to dock windows to the left, right, or bottom of the IDE.
260Figure 14. Docking windows
261Auto Save in the IDE
262To prevent loss of information due to inadvertently closing unsaved file changes for example, the IDE
263now auto saves your work on a regular basis and should the IDE crash, it will prompt you to recover your
264work when you restart.
265Figure 15. Auto saving files
266Change Tracking
267Change tracking makes it easy to visualize the differences between saved and unsaved code.
268In the figure below, you'll notice that the far left pane is colored differently for certain sections of code.
269The code highlighted in yellow represents new code that has not yet been saved, while the code
270highlighted in green represents new code that has been saved. Code that is neither yellow nor green
271represents code that existed when the file was originally opened.
272Figure 16. Change tracking
273New Windows Forms Controls
274Windows Forms for Whidbey adds several new controls ranging from improved data controls like the
275GridView, to new controls like the Sound control for audio, and the Winbar control for customizable
276menus.
277Figure 17. Winbar Control
278New Web Form Controls
279ASP.NET has several new enhancements to dramatically improve developer productivity. Several of
280these features are available in new ASP.NET control categories, like Personalization, Security, Validation,
281and Navigation. For a full list of Visual Studio enhancements for Web developers, visit
282http://msdn.microsoft.com/asp.net/whidbey/ .
283Control Alignment
284Aligning controls in the designer is much easier in Whidbey. In the example below, when a user drags
285button 2, a set of alignment lines appear to visually show how Button 1 is aligned with button 2.
286Figure 18. Aligning controls
287Smart Tags for Controls
288Smart Tags have been added for controls that show the common tasks associated with that control, like
289formatting and connecting to a datasource.
290Figure 19. Smart tags on controls
291Quicker Web Projects
292To create Web projects for Whidbey, you no longer need to have IIS installed. Simply select a site to
293create and Visual Studio will allow you to create a website on a fileshare that you can run and debug
294locally.
295SQL Server 2005 Project Support
296Visual Studio Whidbey also includes support for building applications for the next version of SQL Server,
297SQL Server 2005.
298Figure 20. Creating a SQL Server 2005 Project
299Debugger Enhancements
300Enhanced Datatips
301While in debug mode using Visual Studio .NET 2003, you can place the cursor over a simple variable like
302a string to inspect its value. In Whidbey this has been greatly enhanced to handle much more complex
303types. In the figure below, the Datatips show information about a complex type and also includes the
304ability to drill into the hierarchy for that type.
305Figure 21. Enhanced Datatips
306Visualizers
307In Visual Studio .NET 2003, there wasn't a simple way to see complex types like Datasets, bitmaps, and
308so forth directly in the debugger. Visualizers are a way to visually represent data while in debug mode.
309For example, you can visualize the contents of an XML string by selecting the XML visualizer directly from
310the Autos window as shown in the figure below. Visualizers are also fully extensible so developers and
311component providers can create custom visualizations for their own types.
312Figure 22. Visualizer options
313Figure 23. XML visualizer
314New Symbol Server Options
315If you wanted to use a symbol server in Visual Studio 2003, you had to setup a system environment
316variable like:
317_NT_SYMBOL_PATH=srv*E:\Cache\Symbols*http://msdn.microsoft.com/downlo
318ad/symbols;
319And this could only be done before debugging. In Whidbey, we have made it easy to setup multiple
320symbol server locations and set the path to your local symbol cache. You can also setup up your symbol
321server after you are in break mode, which can be useful when you realize the debug symbols have not yet
322been loaded.
323Figure 24. Symbol server options
324Design Time Expression Evaluation
325In Whidbey, the Immediate window can now be used to evaluate expressions at design time without
326having to compile and run the application. In the example below, the Add method is called directly from
327the immediate window without having to leave the design time environment.
328Figure 25. Evaluating methods in the immediate window at design time
329Configurable Security Permissions
330Whidbey simplifies testing different security credentials by enabling developers to debug their
331applications with configurable security permissions.
332Figure 26. Configurable Security Permissions
333Summary
334Visual Studio Whidbey builds on the success of Visual Studio 2002 and Visual Studio 2003 to make
335developers even more productive then ever before. With the new language constructs, compiler features,
336productivity enhancements, and debugger improvements, developers will be able to create more
337powerful applications in less time and focus on writing code</string></string></t></t></t></t></t></customer></customer></customer></customer></int></int></int></int></itemtype>