Display Full Signature

Wed, August 10, 2005, 12:35 PM under Whidbey | VisualStudio
It seems the promise is delivered in the Visual Studio 2005 June CTP.

The first clue is on the Class Diagram toolbar and menu.

With Beta 2 there is a menuitem (and toolbaritem) that reads "Display Member Types" and it can be on or off - to either display the return types of methods and the types of fields/properties... or not.

With June CTP, there are 3 options as the following screenshot shows:

For a VB example of what a class on a diagram looks like when we "Display Full Signature", click here.

Before I show you a more involved C# example let me share with you a tip: Since VS2005 allows you to reference assemblies built with VS.NET 2003, even if you are not planning on moving to VS2005 any time soon
, you can visualize the publics of your assemblies with VS2005; in other words, use VS2005 just for the Class Designer so you can draw your class diagrams!

1. In VS2005 add a reference to OpenNETCF.dll
2. Switch to Class View and make sure "Show Project References" is checked
3. Drill in the Project References until you reach the namespace OpenNETCF.ComponentModel
4. Now right click on it and choose View Class Diagram

There you have it. A class diagram showing the BackgroundWorker and its friends :-)

I followed the steps above in a C# project and the results, with full signatures, are here.


Tue, August 9, 2005, 12:27 PM under Whidbey | VisualStudio
If you look at the form designer generated code (InitializeComponent and friends), when you add a control to your form, you'll see that the control gets created, sized, positioned etc and then finally added to the Controls collection of the form. That is all fine and necessary, what is not always necessary is having a form level field that points to the control. It is an extra 4 bytes per member and more importantly clutters the code and intellisense (and any diagrams you auto generate).

In this area, there is a small enhancement that I loved when I first saw Whidbey and I don't think it has had enough coverage, so here goes.

In Visual Studio 2005, when having a form open, you can select a control and toggle a new boolean property from the properties window (under the Design category): Generate Member. As the documentation says, it "Indicates if a member variable will be generated for this component."

So for all those projects you have upgraded, go though the controls on your forms and check to see if you are accessing the control variable outside InitializeComponent; if you are not set GenerateMember to false. For new projects make sure you remember to make that decision every time you add a control to your form; e.g. most Label instances never get accessed after you set their Text in the designer.

Note that this is not a true property, i.e. you don't get programmatic access to it of the Control class. It is simply a design-time thing done via an extender no doubt.

ProjectProperties->Signing vs AssemblyInfo

Sat, August 6, 2005, 05:54 AM under Whidbey | VisualStudio
This has been on my "to blog" list but, since someone else beat me to it, please go read: Visual Studio 2005 and Signing with strong name keys.

Why is there a warning against using the old way of signing in the AssemblyInfo.cs? When sharing code between Smart Device and desktop projects, we used to share the AssemblyInfo file. Now, to strong name both projects/assemblies, I need to do it via two different project properties dialogs rather than a single code file!
Note that VB projects seem more tolerant to using the AssemblyInfo.vb for this purpose.

In addition, there is another bug with Beta 2. Say you created a desktop project and added the strong name (resulting in the silly copying of the snk file to your project folder). Now you create a Smart Device project in the same folder and using *its* project properties try to add the snk file from its original location: VS2005 dies a horrible death! The workaround is to browse to the snk file that was copied in your project folder.

Project properties nuisance

Fri, August 5, 2005, 12:54 PM under Whidbey | VisualStudio
Nobody likes modal dialogs, but the Visual Studio.NET 2003 properties dialog is *not* modal.

Nevertheless, we prefer docked windows (apparently), so in Visual Studio 2005 the properties window is "inlined" in the main area as if it were a code file.

With this change we lost a great usability feature. Easiest way to describe this is an example:
1. Open a VS2003 solution with more than 1 project (e.g. 3 or 10)
2. Collapse them all [btw, when are we going to get a "Collapse all" in VS?!]
3. Select a project and choose Project Properties to show the popup window
4. Select "Common Properties" -> "References Path"
5. Change the value(s) (or verify it is what you want)
6. Without closing the dialog, select another project in the solution
7. See how the “project properties” updates for that project?
8. Go back to step 4 and select some other section of the Properties dialog
9. In solution explorer, use the keyboard up/down keys to quickly verify that a setting is the same for all projects

I use the above all the time (e.g. to quickly toggle Debug/Release constants, change default namespace etc). When you change project selection, if you have made changes, you get the prompt to save or discard changes (which is nice).

So how can I achieve the same with VS2005? That wasn't a rhetorical question... please tell me!

For all projects in a VS2005 solution, try to change the output path from bin\Debug to bin\DebugCF. Count the number of clicks/mouse movements and do the same for VS2003 in no time.

How irritating when a great product takes a step backwards...

...or maybe I should get out more ;)

How to upgrade VS2003 projects to VS2005

Thu, August 4, 2005, 01:04 PM under Whidbey | VisualStudio
If in Visual Studio 2005 you try to open a project created with Visual Studio .NET 2003, the conversion wizard appears. Apart from the option to backup the existing solution, there isn't much more to it other than clicking the "Finish" button. It basically takes the project file (which is v7.1 or v7.0) and converts it to VS2005 (v8.0); all code files (.vb or .cs) remain untouched.

When you install VS2005 you can quickly tell in your file explorer which solutions were created with which version of Visual Studio, check out this screenshot.

Note that if you double click on a 7.x *project* file in explorer, you will be presented with the upgrade wizard in VS2005, whereas doing the same for a 7.x *solution* file, correctly opens it in VS.NET 2003.

So I was upgrading some VB device projects with Beta 2 and noted a few subtle differences between the *upgraded* VS2005 projects and *new from scratch* VS2005 projects of the same type. The differences are easier observed by opening the project files in notepad (or an XML editor) and comparing them (you know of course about MSBuild).

For example, the upgraded project has a bunch of empty tags (which are not needed): ApplicationIcon, AssemblyKeyContainerName, AssemblyOriginatorKeyFile, AssemblyOriginatorKeyMode, StartupObject and PreBuildEvent/PostBuildEvent under PropertyGroup under FileUpgradeFlags. It also has a bunch of tags with default values (whereas new projects omit them) or tags that don't apply to NETCF projects: DelaySign, OptionCompare, OptionExplicit, OptionStrict, RegisterForComInterop, RemoveIntegerChecks, TreatWarningsAsErrors, WarningLevel and Name/Private under Reference Include under ItemGroup.

Newly created projects will have the new properties structure I described previously here. You can observe this in the new files in the text editor with tags such as: AutoGen/DesignTimeDependentUpon under Compile Include for Resources.Designer file. Also for tags such as: Generator/LastGenOutput/CustomToolNamespace under EmbeddedResource Include for Resources.resx file.


If you still wish to go down the upgrade wizard path for your VB device projects, here are my recommendations for your project properties window:
1. Select Option Strict On
2. Select “Error” as the Notification for all Conditions except "Use of variable prior to assignment"
3. Check "Treat all warnings as errors"
4. Check "Generate XML documentation file"
5. Go to "Advanced Compile Options". On the "Generate debug info" combo, select "Full" (at least for a debug configuration) DebugType
6. Go to references and remove unused ones (Unused References->Remove)
7. Uncheck assembly COM-Visible [unless you explicitly want it to be visible]
8. If you want AssemblyInfo in its own folder, create one in the project and move it there.

Alternatively, if you want clean projects following the new style:
a) Create a brand new project in VS2005 (of the same type as the one you will upgrade)
b) Delete the default code file (e.g. Form1 or Class1 etc)
c) Copy attributes from the old AssemblyInfo file to the new one as appropriate
d) Copy settings from the old project properties to the new one as appropriate
e) Add references to the new project to match the old ones
f) Deal with resx files as discussed here

Finally, and continuing from my last point above, it makes sense that you upgrade your projects (one way or the other) bottom up. In other words, start with your class library that references nothing but framework assemblies and work the projects up to your Application (the exe). Note that VS2005 will allow you to reference assemblies built against v1 of the framework! So be sure you are referencing *upgraded* dlls and not the original/old ones.

AssemblyInfo 1.0.* ->

Wed, August 3, 2005, 09:24 AM under Whidbey | VisualStudio
In VS2005 the version number does not default to "1.0.*" like it does with VS.NET 2003. Instead it starts off with more sensible "". You can check this for yourself by examining the AssemblyInfo file (or through the project properties and the "Assembly Information" button).

However, I would prefer a checkbox on the dialog (or a wildcard character in the file) that would result in auto-incrementing the revision part of the version. This is exactly what VS2005 offers for ClickOnce application and you can see that for yourselves by navigating to the "Publish" of the project properties dialog ("Automatically increment revision with each publish").

To be perfectly honest, what I would really like is to pass to the AssemblyVersion attribute the following parameter "1.0.*.0". I would then expect the build part of the version number to increment by one every day as it does now, to indicate the number of days since January 1st 2000. Alas, we cannot add anything after the *... maybe in Orcas!

Another use of partial types

Tue, August 2, 2005, 04:03 PM under Whidbey | VisualStudio
We've looked at partial types before but what use are they?

Their primary use is for code generation tools. The main/best example is the windows forms designer which uses them for splitting the designer code from the code we (the developers) write. I think that code generation will play an even larger part in every day development as years go by but that is another story...

Another use could be to split a class in privates and publics. So one file has all the (private) fields and private methods while the other has all the members that are externally callable.

You can take the previous idea too far and have a file per member category i.e. one for fields, one for methods, one for properties and one for events (or even another for internal types such as structs/classes/delegates).

If a class implements an interface (or many), why not split the interface implementation into its own file...

Some might even split a class into files according to the areas that different developers are working on (thus assisting with source control check ins/outs).

Finally, if you find yourself declaring your own code regions in VS.NET 2003, consider whether you can extract them into their own file using partial classes.

I am not advocating any of the above but I am not being a purist against it either. For the record, I do believe that classes should be controlled from growing too large; objects should be designed to do one thing only and do it well.

Recently I discovered another reason. A few years back, when I migrated a whole bunch of dotnet code to the compact framework, I came across types that while designed to do one thing only, they had a fatter interface than what appropriate for an embedded platform (and some of their members were simply not applicable to windows ce). There were a number of approaches I took depending on the situation:
1. "Carry" the extra class members but not call them
2. Conditionally compile parts of the class for the NETCF (or vice versa)
3. From a single class, extract a base abstract class and two specialisations (each in their own file). In the Smart Device Project I only use two files out of the three (the base class and only the one subclass that is applicable).

It is obvious where this is going, isn't it? :-)

A 4th option with Visual Studio 2005 is to use partial classes and thus exclude the files you don't want from one of the projects. One more support option for sharing projects between the two platforms.

My Project Properties

Thu, May 19, 2005, 03:23 PM under Whidbey | VisualStudio
With Visual studio 2005 the contents structure of Solution Explorer has changed. Even with VS2003 I always had the "Project->Show All Files" option turned on but with VS2005 it is essential (by default, they hide more than what they show!).

The main change is that under each project there is a folder (just above "References"). Amongst other things it contains the AssemblyInfo file (that previously was with all the other files). If you open the project properties and go to the "Application" tab you'll find a button called "Assembly Information" that brings up a dialog showing the AssemblyInfo values. If for whatever reason you’d prefer the AssemblyInfo file to live with the other code files, then simply drag it out; the project properties will still find it :-)

Under the same folder you'll find a Resources.resx file (and its dependent Resources.Designer). Again, you can manipulate this via the project properties and specifically the "Resources" tab. It is these files that enable My.Resources (and the Resources class in C#) wrapping the System.Resources.ResourceManager. If for whatever reason you’d rather not have these files, then right click on them and delete them (you can always regenerate them via the project properties “Resources” tab).

All of the above is applicable to projects targeting PC or devices and is true for both VB and C#. Of course, keeping the name of the folder the same for both languages would be sacrilege so in VB it is called "My Project" and in C# it is called "Properties".

Furthermore, only for desktop projects (you didn't think we'd have it all in the Compact Framework did you?), the folder also contains Settings.settings (and its dependent Settings.Designer) files. As you guessed, these enable the editing of settings in the project properties based on an auto-generated Settings (My.Settings in VB) class that inherits from System.Configuration.ApplicationSettingsBase). If for whatever reason you’d rather not have these files, then right click on them and delete them (you can always regenerate them via the project properties “Settings” tab).

Finally, only for VB desktop projects, the "My Project" directory contains the files: Application.myapp, Application.Designer.vb and ApplicationEvents.vb. These are responsible for the new startup model and application level events, which we looked at in the Beta 1 timeframe (it has changed slightly but the majority is identical and the changes are mostly cosmetic e.g. the option is now called "Enable Application Framework" rather than "Startup with custom Sub Main"). If you don’t want the ApplicationEvents.vb file, then simply delete it (you can always regenerate it via the button “View Application Events” under the Project->Properties Application tab). Whatever you do, *do not* delete the other two vb files; with Beta 2 at least, nasty things can happen (things that force you to use Task Manager -> End Task)! Having just said that, those two files are also present in Class Library projects even though the relevant project properties areas are disabled (!). In the class library case it seems safe to delete them.

Class Designer news

Wed, May 18, 2005, 02:57 PM under Whidbey | VisualStudio
Due to numerous fundamental omissions, the Class Designer has a long way to go before it can fully compete with existing modelling tools (although it already beats them hands down in some areas). The only devs who don’t see that are quite frankly those that haven’t used on a regular basis UML tools before (either due to not having the chance to do so _or_ because they tried and quickly quit due to the high UML learning curve).

Today, two posts in the class designer forums renewed my faith in the tool big time.
1) Full signature support in RTM (look for contribution by Ramesh on 18 May)
2) A cool open project that seamlessly adds a whole bunch of features (including showing all fields as associations for selected types). Shame about the gotdotnet choice Dmitriy, but you can’t have it all I guess :-)

Good stuff, thanks guys!

NoWarn or VB compiler options

Tue, May 17, 2005, 12:44 PM under Whidbey | VisualStudio
With VS2005, if you open the project properties of a VB project and select the "Compile" tab, you'll see a bunch of options.

[digression]Why did the VB team call it the "Compile" tab, whereas the C# team call it the "Build" tab? Although it is a rhetorical question, I'll answer it: Because the two teams do things differently for the sake of it! Consistency between the two is not only not a requirement, but probably looks bad at review time, so they avoid consistency as much as possible. Anyway...[/digression]

So you are on the "Compile" tab and you can choose between the None|Warning|Error notifications for each of the following 9 conditions (we'll see in a moment what the 5-digit numbers are after each one):
1. Implicit Conversion - 41999, 42016
2. Late binding call could fail at run time - 42017,42018,42019,42032,42036
3. Implicit type; call could fail at run time - 42020,42021,42022
4. Use of variable prior to assignment - 42030,42104,42108,42109
5. Function/Operator without return value - 42105,42106,42107
6. Unused local variable - 42024
7. Instance variable accesses shared member - 42025
8. Recursive operator or property access - 41998,42004,42026
9. Duplicate or overlapping catch blocks - 42029,42031

I will not explain each one here, because I hope they are self-explanatory. When you turn On Option Explicit and Strict you'll see that the top 3 are automatically set to Error.

So that leaves the remainder 6. I advise you to set the last 5 to Error; I cannot think of a reason why you would not want to correct issues caught by the compiler - if you have come across a reason, please debate it with me.

So we are now left with Use of variable prior to assignment: Set this to None. The feature is not complete and I have left comments here and submitted the bug here, to no effect. I guess you could turn it on and see if it has caught anything useful and, after wading through a sea of false positives, turn it off again. But this is literally a waste of time.

Finally, let's see what the 5-digit numbers are about. The VB compiler has more than 9 settings; in fact it has at least 24 (represented by the 5 digit numbers). When you make changes to the project properties' tab as discussed above, if you open the vbproj in notepad you'll find a NoWarn tag. Within that tag the series of numbers represents your choices. By enabling one warning at a time, saving and then examining the file, you'll come up with the mapping I have above, e.g.:
The second line instructs the compiler not to bother warning us about possible null reference exceptions. The first line tells it to set all other warnings to errors (this is separate to the "TreatWarningsAsErrors" tag that acts independently on a more generic level).

One question still remains. Why, in some cases, there is more than one number corresponding to a setting? The answer must be because there is finer grained control available that the VB project properties dialog is not offering (in fact, in the C# project properties you can freely enter the corresponding set of C# compiler numbers). Yet another tradeoff between simplicity (i.e. nice UI) and flexibility (i.e. full control).

Attributes in properties of code file

Fri, May 6, 2005, 10:57 AM under Whidbey | VisualStudio
The more I use VS2005 Beta 2 the more I come across (little) new things.

Make sure you have the properties window open/docked (you know, the one where you usually change the properties of controls).

Open a code file (i.e. a class) and place the cursor on the class declaration. Look in the properties window. You can toggle the 3 boolean combobox options to insert/remove the 3 corresponding attributes: COM Class, COM Visible and Serializable.

This appears to be a VB thing only. It's been a while since I said that in a positive way :-)

Now, would the VSD (Visual Studio for Devices) team please remove the Serializable option, as it does not apply to CF?

CLSCompliant now works

Tue, May 3, 2005, 02:02 PM under Whidbey | VisualStudio
VB Class Library projects are marked at the assembly level with CLSCompliant (while in C# you have to add it yourself). The most important reason for turning it on in your C# library projects is so that you don't accidentally expose case sensitive *publics*; not only this is not CLS compliant, but it would render your assembly unusable by VB code.

So, while it is bizarre that the option is not turned on for C# by default and it is for VB, it makes no difference because it has no effect for VB projects! The situation changes with Whidbey, where suddenly it works as expected. I guess it got noticed when VB got support for unsigned types (also not CLS compliant).

How did I find out? Some of my assemblies are exposed to VB6 clients, so I have public interfaces starting with an underscore (representing the default interface) and other starting with double underscore (representing the default events interface). When I upgraded them to VS2005 B2, I got a whole bunch of CLS compliancy errors (no public types may start with _). BTW, my solution was to mark them as CLSCompliant(false) rather than tweak the public interfaces and then have to modify all clients too.

FYI, with Whidbey, the C# team persists with their choice of not marking the C# projects with the CLSCompliant attribute by default... is that arrogance?

Synchronize Class View

Mon, May 2, 2005, 11:59 AM under Whidbey | VisualStudio
When in the code editor of Visual Studio, one of the items I use most on the context menu is the "Synchronize Class View" menu item. As you expect/know, it activates the "Class View" docked window, expanding the tree nodes as appropriate and selecting the item which you have the cursor on in the code. I love this feature, and my jaw dropped when I couldn't find it on the VS2005 context menu!

I quickly went through the top level menus and their children trying to find where this option lives; no joy. Since every action in VS has a keyboard shortcut, I thought I'd go to the Tools->Options->Environment->Keyboard and see if I can find it that way. Lo and behold, it appears as the 5th item in the auto-filtered list as soon as I type "Sync": View.SynchronizeClassView. I cancel the Options dialog with a smile :-)

Armed with this knowledge (i.e. that the option lives under View), I can add the option to the context menu. Here are the steps, if you wish to do the same:
1. Select Tools->Customize
2. On the Toolbars tab, check the "Shortcut Menus" item
3. Observe how 6 drop down menus appear on the toolbar, the first one being "Editor Shortcut Menus"
4. Still in the Customize dialog, select the "Commands" tab, select "View" on the left and locate on the right the "Synchronize Class View" item.
5. You can now drag the item to the "Editor Shortcut Menus" and drop it wherever you want (I placed it on top of "Go to Definition")
6. Close

Editor life is back to normal again...

New Compilation Constants

Sat, April 30, 2005, 05:45 PM under Whidbey | VisualStudio
Dotnet projects have at least two configurations: Debug and Release. Part of the configuration is the definition of two compilation constants: DEBUG and TRACE. For Debug configurations, both constants are on; for Release, only TRACE is on. I always turn TRACE off as well, and I advice you to do the same (however, that is not the point of this blog entry).

You can tweak these in your project properties (they are represented by checkboxes) and you can also add your own in the textbox offered or you can define them in code (#define or #const, depending on your language of choice). An example of why you would add a compilation constant is for cross platform development, as detailed before.

For conditional compilation you use #if. In C#, the code that does not apply gets greyed out. This is really sweet and somehow I thought it was added to the VB2005 IDE, but unfortunaly I realised recently it wasn't :-(
Go vote for it (maybe it will make the Orcas release).

In VS2005 we find a few additional conditional compilation symbols that are not in VS.NET 2003 (applicable or not, based on what project type you chose and what language you are developing in):

I'll let you figure out what each one is used for and the potential values they can have ;-)

Tiny (but positive) change

Fri, April 29, 2005, 01:09 PM under Whidbey | VisualStudio
Just noticed a infinitesimal change in VB code with Whidbey that will make copying pasting from C# to VB and vice versa require one less thing to look for.

As you know, code for properties in VB is autogenerated:
Public Property SomeProp As String [hit enter here]

The setter looks like this in VS.NET 2003:
Set(ByVal Value As String)

In VB2005 Beta 2 it looks like this:
Set(ByVal value As String)

Seems like the VB team had their ear pulled by the coding/naming guidelines department :-)

February CTP

Thu, March 31, 2005, 12:06 AM under Whidbey | VisualStudio
We know the February CTP contains older device bits than the November CTP, but since the DVD arrived through my letter box I thought I'd install it (yes I have better things to do but I was curious alright :-)

My goal was to find 5 things I didn't know about (not necessarily new in this CTP) *and* they should not be CF-specific.

1. PropertyGrid control. I hadn't noticed that this is now part of the default toolbox for winforms. BTW, if you want to use it today with VS2003, see this.

2. Object Test Bench for VB :-) They told me they would not do it. If you've got the Feb CTP, go play with it (e.g. follow the C# steps described here).

3. This has been true since Whidbey went public, but I only just noticed it. If in a C# project (or with VS not having any project loaded), you open a VB file, its regions are recognised :-) [This always pi**es me off with VS2003]. A related nice option is "Tools-Options-Text Editor-File Extension"

4. You know about partial classes. Well, VB still doesn't show us the constructor in the file we edit by default (like C# does) :-(

5. Select the menu "Class Diagram-Display Types". I guess this is a tiny step closer to having method signatures but until that happens... Anyway, there are other reasons to moan about once you observe how this is implemented in C# as opposed to VB. The way I see it, this is another blow for VB developers.
"You cannot cope with UML notation for return types, which is simply replacing 'As' with ':' *but* C# developers are perfectly capable even though the change is larger (moving the return type from the front of the method name to the back and precede it with a colon)."
As a UML shop through and through, this is yet another reason for us not to use the Class Designer (or to ditch VB for any new projects).

Filter Exceptions

Thu, February 17, 2005, 06:31 PM under Whidbey | VisualStudio
Right click on the Output window in VS.NET and you get a lame contextmenu with 3 options: "Copy", "Clear All" and "Go To Error/Tag".

In April 2002 I requested that we are given the ability to exclude first chance exceptions from the output window.

Finally, 3 years later we get what I asked for :-)
Unchecking the "Exceptions" menuitem should turn first chance exceptions off.

It also looks like the Debug->Exceptions dialog has had a face lift...


Mon, January 17, 2005, 10:11 AM under Whidbey | VisualStudio
This is the title of a blog post that immediately got my attention. I had to dig further, so here is the process.

Look at the attribute with a decompiler:
[AttributeUsage(AttributeTargets.Delegate | (AttributeTargets.Parameter | 

(AttributeTargets.Interface | (AttributeTargets.Event |
(AttributeTargets.Field | (AttributeTargets.Property |
(AttributeTargets.Method | (AttributeTargets.Enum |
(AttributeTargets.Struct | (AttributeTargets.Class |
AllowMultiple=true, Inherited=false), ComVisible(true)]
public sealed class ObfuscationAttribute : Attribute {
// Constructor
public ObfuscationAttribute();

// Properties
public bool ApplyToMembers;
public bool Excludet
public string Feature;
public bool StripAfterObfuscation;

// Fields
private bool mApplyToMembers;
private bool mExclude;
private string mFeature;
private bool mStripAfterObfuscation;

If you think drilling deeper will tell you anything, don't hold your breath; the properties are plain accessors for the fields and this is the ctor:
public ObfuscationAttribute(){

mStrip = true;
mExclude = true;
mApplyToMembers = true;
mFeature = "all";

OK, so the class itself doesn't unveil the mystery, but maybe applying it to one of our methods and then examining that will:

public int ObfuscateThisPlease() {
int j = 6;
int i = 5 + j;
return (j - i);

.method public hidebysig instance int32 ObfuscateThisPlease() cil managed
.custom instance void [mscorlib]ObfuscationAttribute::.ctor()=(01 00 00 00)
// Code size 10 (0xa)
.maxstack 2
.locals init ([0] int32 j,
[1] int32 i)
IL_0000: ldc.i4.6
IL_0001: stloc.0
IL_0002: ldc.i4.5
IL_0003: ldloc.0
IL_0004: add
IL_0005: stloc.1
IL_0006: ldloc.0
IL_0007: ldloc.1
IL_0008: sub
IL_0009: ret
} // end of method Program::ObfuscateThisPlease

Nada. Tzifos. Nothing. At this point there is only one thing left to do: RTFM, and all is revealed:
"Instructs obfuscation tools to take the specified actions for an assembly, type, or member."

Well I bet, like me, you guys (and gals) were hoping System.Reflection.ObfuscationAttribute would be a pseudo-custom attribute rather than just a marker for 3rd party tools, but not every journey leads to a treasure :-(

I guess I could be applying it to all my privates automatically since, as we know, custom attributes cost absolutely nothing, until you explicitly reflect on them.

(Just to get this out of my system: I think the term Attribute is an unfortunate choice by the .NET designers. "Annotation", "decoration", "declaration", “metadata” or anything else would have not only conveyed the purpose better, but would also not clash with the UML's existing use of the keyword "attribute" to mean fields/data_members of a class)

DV Sample

Thu, January 6, 2005, 02:16 AM under Whidbey | VisualStudio
As the sample I promised, I have written a visualizer for System.String. Given a string variable, it will show the bytes corresponding to that string based on the various encodings. The inspiration for it was the cry that a friend of mine got from their QA team recently regarding an app they have that "Doesn't work on a Chinese OS!".

To create it, we need a class library project that references Microsoft.VisualStudio.DebuggerVisualizers.dll and we add the following code:

1. Declare the attribute:
[assembly: System.Diagnostics.DebuggerVisualizer(

Target = typeof(System.String),
Description = "Encoding Viewer")]

The above is all you need to enable the new menu item when you hover over a string variable (or in the Autos window). In the IDE, the menu looks something like this. Note how VS2005 gives us out of the box the HTML, XML and TEXT visualisers.

2. The code that runs when the "Encoding Viewer" menuitem is clicked, is in your class:
using Microsoft.VisualStudio.DebuggerVisualizers;

namespace EncodingVisualizer {
public class StringBytes : DialogDebuggerVisualizer {
protected override void Show(IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider) {
string s = (string)objectProvider.GetObject();
frmStringBytes f = new frmStringBytes(s);
Naturally, you need a form frmStringBytes whose visual design looks like this; the constructor of the form does the work and is straightforward:
public frmStringBytes(string aString)

: this() {
txtExpression.Text = aString;

string s;
byte[] arr;
arr = System.Text.Encoding.ASCII.GetBytes(aString);
s = "ASCII = " + BitConverter.ToString(arr);
s += "\r\n\r\n";

arr = System.Text.Encoding.Unicode.GetBytes(aString);
s += "Unicode = " + BitConverter.ToString(arr);
s += "\r\n\r\n";

arr = System.Text.Encoding.Default.GetBytes(aString);
s += "Default = " + BitConverter.ToString(arr) + "\r\n";

// Do other encodings here e.g UTF7, UTF8, UTF32 etc

txtValue.Text = s;
You may download the dll and place it in the right place as discussed before.

Debugger Visualizers in Nov CTP

Tue, January 4, 2005, 05:26 PM under Whidbey | VisualStudio
Apart from Tracepoints (as hinted at the last sentence of that post), the most exciting debugging enhancement in Whidbey is the Debugger Visualizer support. If you are already familiar with VS2005 Debugger Visualizers, here you'll find what has changed with the latest Community Technology Preview (btw, the Dec is not the latest CTP from a framework version perspective, the Nov one is). If you are not familiar with the feature, I suggest you follow these links [ 1 , 2 , 3 , 4 ] and note the changes from previous versions detailed below:
1. The assembly reference must be to: Microsoft.VisualStudio.DebuggerVisualizers
2. The DebuggerVisualizer attribute ctor doesn't need the 3rd param i.e. delete the VisualizerUIType parameter as all visualizers are modal now.
3. Your class that implemented the Show method of IDebugVisualizer should now inherit from DialogDebugVisualizer and override the Show method; the signature for this now is:
void Show(IDialogVisualizerService, IVisualizerObjectProvider)
Of course, you need to imports/using System.Diagnostics and Microsoft.VisualStudio.DebuggerVisualizers; the location for visualizers (assemblies/dlls) is still the same: "My Documents\Visual Studio\Visualizers" or "[VS8]\Common7\Packages\Debugger\Visualizers"

That's all. If you didn't know about Debugger Visualisers and have downloaded the Nov CTP, follow the links at the top (and below), download their samples, make the appropriate changes and have fun!

Next time I'll implement a DebuggerVisualizer (not an Image Visualizer, which you can get here, here and here) so you have a complete sample to download.

December CTP failure

Fri, December 24, 2004, 03:58 PM under Whidbey | VisualStudio
Microsoft Visual Studio 2005 Beta 2 Setup
Error 1305.Error reading from file d:\vs\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bootstrapper\Packages\InstMSI\instmsiA.exe. Verify that the file exists and that you can access it.
Retry Cancel

I have been trying all day to get the December CTP installed. Every sinlge time the message above halts the show. Yes, the file (and the instmsiW.exe) are both present on the C hard drive and the D dvd drive. The one on the C drive seems to be used by something because it will not let me delete/rename/overwrite it. Maybe there is already too much alcohol in me, but the fact is I can't see a solution and am giving up :-(

Merry (hic) Xmas!

November CTP

Fri, December 17, 2004, 02:01 PM under Whidbey | VisualStudio
As you should be aware by now, there is a November CTP out (I learned about it here). Thought I'd briefly share some experiences on the sleek VS2005 Standard Edition.

The install went though OK, including launching VS. Creating a project was not so smooth though; some error about System.XML being corrupt. Repaired the installation and tried again: bingo! So now I do my usual thing of creating one of each Windows App and NETCF app (in both C# and VB) to see if it is worth continuing and yes, it all worked. Then turned my focus to CF projects only (if you are asking "why", welcome to my blog :-).

First noticeable omission compared to the Beta 1 (the October CTP escaped me), is Deploy to My Computer! Where has it gone? That was way cool (previously mentioned it in passing here - penultimate paragraph) and I hope it will come back before Whidbey RTMs. UPDATE: If you also want this feature back, GO VOTE FOR IT NOW (it has been cut and is not on the list for RTM.

Looking into the above further, I actually try to execute a CF exe on the desktop and it fails to find the right assemblies (exception and death). This also worked before and works today with VS2003! So I move the exe to the actual directory where the CF assemblies are, and now it works... interesting.

Major setback now: I cannot debug with the emulators (I am running XP in a VPC). This worked in Beta 1, so it is either a step backwards or something wrong with my installation. Just running up the emulators works fine, by the way. Taking that last step further, I decide to manually copy the exe to the emulator (even a plain deploy with VS doesn't work). I can now run the exe and have a play with it (after also copying the CF 2.0 cab and installing it, of course). BTW, sharing files is made much easier with the direct option to have a "Shared Folder" in the options of the emulator; it then appears as "Storage Card" in the image. UPDATE: Got emulator debugging working with thanks to Amit Chopra (Brian Chamberlain really).

Next thing to examine are the NETCF framework assemblies in ILDASM (yes I like Object Browser and other tools but I prefer exploring what's new through ILDASM - call me crazy). I like what I see, but this is not the purpose of this blog entry. I find a couple of areas of particular interest and decide to drill into them (as in look at the implementation of the methods). No IL!!! All methods have a code size of 1, which is the ret statement. What's going on here? I open the CF assembly I just created and, sure, I can see the IL fine. Also fine are the desktop framework assemblies. I must be missing something here but I have never encountered this before, so if anybody has any clue please share. UPDATE: Turns out with this release the CF assemblies on the desktop are just designer shims and have no real code in them; the workaround for examining non-publics and implementations is to copy the files from the device to the desktop and disassemble them - thank you to Mike Zintel and his team for pointing this out. BTW, if you don't fancy copying the files and can cope with unfriendly file names, just extract the appropriate cab files directly on your PC :-)

I'll update this entry with any relevant info, but that's all for now. Next time we'll see a cool addition to CF 2.0 that was not in the Beta. At some future date I will cover Generics, which are also available in this build.


Thu, November 4, 2004, 03:59 PM under Whidbey | VisualStudio
If you are not familiar with the new My feature of VB2005, please go read about it and make your own mind up. I suggest reading my previous entry (in addition to the two links I offer there also check these out [1,2])

So it is clear that we are talking about:
1. A speed dial into the framework
2. Application events
3. Stuff generated at compile time into your project

My opinion is that the first one is a waste of space. Speed dial?! They could have given us this as example code and be done with it (or invest the energy to improving the help/navigation system). Yes the framework is large and some times discovering some methods may take longer than what it should, but how does having a parallel framework help? Now I have two frameworks to learn! We don't need YAF (yet another framework). The process of discovering the framework is called "becoming a .NET developer". While searching for a solution to a problem, the developer discovers not only the correct namespace/class/method but also a bunch of other classes/methods that they will not have to search for next time they have a different problem. The My feature discourages this behaviour and hence hinders learning the framework (which can only be a bad thing).

I wasn't too thrilled with VB.NET 2002 when I discovered all those "global" functions that come as part of Microsotf.VisualBasic.dll However, there is a major difference with those: they are necessary for smooth upgrade of VB6 code by tools (and some parts of it actually offer functionality not found in the framework). VB2005 takes the VB6 approach of having global functions everywhere and repackages them in a structured library. Structured or not, it is still a bunch of globals that existing .NET devs did not need (globals=statics.. err sorry I meant shared). In case it is not clear yet, My is a bunch of stateless operations that offer functionality already available in the framework. It is obvious the feature was added to lure VB6 devs that have not yet moved to .NET, but is My really helping them in the long run?

Application events as a concept are a nice idea. Will I use them in VB? Unfortunately the answer is no. Not only I am not too fond of having to give up my own Sub Main, but more importantly they will not be supported in CF 2.0

I haven't made my mind up on whether I like the 3rd part of My. On the face of it, it seems dirty, but only time will tell.

To finish off with a sweeping comment on the whole of the My feature: it is nowhere near in the same league as refactoring (that will not be part of Whidbey) and I would like to talk to the person that was responsible for prioritising these features (not that it will happen, but it doesn't hurt to ask:-).

I had written the above and then came across a post with a similar ending to mine.

Invoke with Whidbey

Fri, October 1, 2004, 05:30 AM under Whidbey | VisualStudio
Last time we looked at Control.Invoke on both CF and full framework. Assuming you have read it, let’s look at VS2005.

On the desktop, if you forget to use Control.Invoke, you now get an InvalidOperationException with the Message: "Illegal cross-thread operation: Control 'SomeControlName' accessed from a thread other than the thread it was created on." That is cool, and the stack trace will of course point you to the culprit. Note this only works when debugging in the IDE, and is not available to CF projects. Instead, with Smart Device projects, you get the (catchable) System.NotSupportedException (with the Beta 1 bits).

CF 2.0 brings parity with the desktop; all 3 limitations are removed, so you don't need the ThreadPool or the Queue or the need to cast:

// ...or any other type/params you want
delegate void SomeCustomDelegate(object o);

// This method runs on a non-GUI thread e.g. Threading.Timer
internal void OnNonGuiThread(Object o){
// if you have more than one argument just add it to the array
object[] arr = {o};

// assuming all this code is in a form
this.BeginInvoke(new SomeCustomDelegate(UpdateBox), arr);

// This method runs on GUI thread
private void UpdateBox(Object o
/*other arguments as defined by SomeCustomDelegate*/){

// TODO use o and other arguments
this.Text = o.ToString();

Ladybug Suggestions

Wed, September 22, 2004, 03:43 PM under Whidbey | VisualStudio
If you are playing with VS2005 you must be familiar with the MSDN product feedback center. Anybody can basically make suggestions for enhancements and also report bugs (it goes without saying that the two are not the same thing)

When I first met it, I thought this was a great idea and immediately starting using it for bug reports and suggestions. Now I am not so sure. The cynic in me has started to believe that the feedback center is there to gather our input for the next version of .NET (i.e. not Whidbey but Orcas). I do hope that is not the case and I will keep using it. I reserve final judgment for when the product ships.

The reason I have started having doubts is the number of suggestions that get 'postponed', 'resolved as won't fix' etc. Just randomly browse through the suggestions made and note how many are actually taken on board. Browsing through bug reports reveals that actually MSFT have already caught most of the bugs that we report. The few additional ones that have slipped their net seem to get attention (unlike the suggestions we file).

If you know of any suggestions that have made it into the product do let me know. Naturally suggestions that they had already decided to make don't count (usually these are stated as "Thank you for your suggestion this is how it works in our current builds").

Here is the list of suggestions I was tracking that are postponed [1,2,3,4,5,6] and here are the outstanding ones [1,2,3,4]. Not to mention the 10 postponed suggestions on the Class Designer (detailed in a previous entry)

As I said, my bug reports have all been addressed except for one which is resolved as won't fix; still fighting it.

A couple of other blog entries on the same theme are [1,2]

Rant over :-|

Partial Classes (CF & Full FX)

Fri, September 17, 2004, 02:26 AM under Whidbey | VisualStudio
If you create a new Windows Application project in VS2005 you'll notice that viewing the code for the Form1 class shows very little. All the designer generated code is missing. If you then "Show All Files" in the solution explorer, you can see under the Form1.cs file a Form1.Designer.cs file which upon viewing reveals the designer generated code in yet another Form1 class. If you build the project and look into the assembly with ILDASM, you notice exactly one Form1 class and no indication about this split. The clue to the whole mystery is the keyword "partial" before each class declaration (in fact VB allows one class not to be declared as partial so you'll only see "Partial" in the Form1.Designer.vb file).

So this is a tool thing. You can split a class over multiple files in the same project, as long as you declare them as partial. With forms, note that adding event handler methods or any other methods that you write, appear in the main code file.

To complete the story of how the solution explorer links the two in the manner that it does, we simply look at the .csproj/vbproj file in Notepad or your favorite XML editor. Under the ItemGroup tag you find something like this:

    <Compile Include="Form1.cs">

    <Compile Include="Form1.Designer.cs">

It is the DependentUpon tag that makes a file appear under another in VS. It is being put to very good use with Partial classes.

So here is a money making thought (and you don't even have to turn adsense on). Write a tool/addin that will create these entries. MSFT is not offering anything in the IDE apart for forms, so it is down to tedious manual work at the moment. If I were using it, I'd wish for a menu item when I right click on a code file that offers: "Add Partial". So if I used it on a SomeClass.cs, it would ask me for a name XXX and then create a partial class SomeClass.XXX.cs under SomeClass.cs. The greatest use of this tool would be for upgrading existing projects. When upgrading, VS2005 does not split Form classes, so you have to do all the work manually if you want to fit in with the new environment. Oh, and if you need Beta testers, count me in :-)

IPC with Remoting in .NET 2.0

Mon, September 13, 2004, 07:29 PM under dotNET | Whidbey
If you have .NET apps talking to each other on the same machine today, chances are you are using remoting. Furthermore, you are probably using binary over tcp and have dealt with the idiosyncrancies of handling events over remoting.

So what is new with .NET 2.0 for this scenario? Well, there is now an Ipc namespace, and using it offers performance improvements over the TCP one. To use it you need to change your config files (and of course you are using config files and not setting up the channel programmatically :-).

Assuming your server.exe.config file looks like this, you simply have to change it to look like this:
<?xml version="1.0" encoding="utf-8" ?>

<application name="ServerHost">
<activated type="SomeNamespace.SomeClass, SomeDllName" />
<channel ref="ipc" portName="server">
<formatter ref="binary" typeFilterLevel="Full" />

Assuming your corresponding client.exe.config looks like this, you have to change it to look like this:
<?xml version="1.0" encoding="utf-8" ?>

<client url="ipc://server/ServerHost">
<activated type="SomeNamespace.SomeClass, SomeDllName" />
<channel ref="ipc" portName="client">
<formatter ref="binary" typeFilterLevel="Full" />

The changes may seem obvious (isn't everything once you know it:-), but I would not have figured the above out if it wasn't for Manish G, whose help was invaluable.

Another improvement with .NET 2.0 – well with the IDE really – is the ability to add references to EXE assemblies, not just DLLs. You can do this today via the command line, but with VS2005 you can do it in the IDE as well. This brings us closer to the ActiveX EXE days (out-of-proc COM) where there were only two files. So you can now merge (if that is what your design wishes) SomDllName.dll into the Server.exe and offer the SomeNamespace.SomeClass from it directly.

That's it!

UPDATE: On Ohad's WebLog you can see how to use IPC programmatically

C# with MyEvents functionality

Fri, September 3, 2004, 05:15 AM under Whidbey | VisualStudio
If you are not aware of the MyEvents functionality that VB2005 offers, check out a screenshot and short description here.

The question is how to get the same support in C#. Well it all becomes pretty straightforward if you understand how MyEvents and the new startup model work in VB. I provided an exploration here.

So, armed with that knowledge, in a new C# Windows Application do the following:
1. Add a reference to Microsoft.VisualBasic.dll
2. Replace all the code in Program.cs with the 35 lines of code given below
3. Form1.cs. This is the main form (you could put a button that throws an exception)
4. Add a form Form2.cs. This is the splash screen, no code needed.
5. Build in release mode and run from explorer.

Here is the code:
namespace WindowsApplicationCSusingVB{

public class MyApplication :

public MyApplication():

base.NetworkAvailabilityChanged += new

base.Shutdown +=
new System.Windows.Forms.ShutdownEventHandler

base.UnhandledException += new

base.Startup += new

this.IsSingleInstance = false;
this.EnableVisualStyles = true;
this.ShutdownStyle =

protected override void OnCreateMainForm(){
this.MainForm = new Form1();

protected override void OnCreateSplashScreen(){
this.SplashScreen = new Form2();

private void MyApplication_NetworkAvailabilityChanged(object sender,
Microsoft.VisualBasic.MyServices.NetworkAvailableEventArgs e){


private void MyApplication_Shutdown(object sender, System.EventArgs e){

private void MyApplication_Startup(object sender,
System.Windows.Forms.StartupEventArgs e){

private void MyApplication_UnhandledException(object sender,
System.Windows.Forms.UnhandledExceptionEventArgs e){
e.Exception.StackTrace, e.Exception.Message);
e.ExitApplication = false;

internal static void Main(string[] Args){
(new MyApplication()).Run();
} //end class
} //end namespace

VB2005 Magic – Application Startup and MyEvents

Wed, September 1, 2004, 10:20 AM under Whidbey | VisualStudio
With VS2005, VB gets the My feature. Part of the package is a new startup model and MyEvents.

If you look in a VB project properties, you will find a (unchecked by default) checkbox "Startup with custom Sub Main". Below it there are more "Windows Application Properties", including choosing a Splash screen. There is also a button "View Code" which takes you to the partial MyApplication class - you can also go there by showing all files in the solution explorer and navigating to the MyEvents.vb file under My Project. By using the dropdown you can hook into various events e.g. Startup, UnhandledException etc. So how does this work?

Well the first thing to note is that, if you check the "Startup with custom Sub Main" (and provide your own Sub Main OR use the implicit one of a Form1), then none of the events will be caught, so obviously the two are intertwined. Second, if you use the Class Designer to drag the MyApplication class on a diagram and then display the full hierarchy, you will find that it inherits from WindowsFormsApplicationBase (WFAB), which in turn inherits from ApplicationBase. All of these are in the System.Windows.Forms namespace but are defined in the Microsoft.VisualBasic.dll

To continue the exploration, we build a simple VB WindowsApplication in Release mode and place a Trace.Assert(False, “stack") in its Form.Load event handler. After running the app, we see the stack trace in a msgbox that uncovers the startup call path. Usually we'd expect to see our Sub Main function followed by Application.Run and then a whole bunch of other methods (not of interest right now) ending up in Form1_Load. Instead, we notice that the call stack starts with:
MyApplication.Main -> WFAB.Run -> WFAB.DoApplicationModel -> WFAB.OnRun -> Application.Main etc.

And those methods are where the magic is.
OnRun does the following:
-sets the MainForm to be your main form (via OnCreateMainForm)
-hides the splash screen
-sets up the NetworkAvailabilityChanged event
-calls Application.Run

DoApplicationModel does the following:
-shows the splash screen (via OnInitialize)
-Raises the Startup event (via OnStartup)
-calls OnRun (just described above)
-raises the Shutdown event (via OnShutdown)

So how does all this affect the startup performance of VB apps compared to C#? I don't have that answer, but if you go and look in the methods above, you will find a whole bunch of other objects getting created (relative to thread safety, security etc). Also take into account the call path for the creation of MyApplication, e.g. it is in the WFAB.ctor that the StartupNextInstance event gets hooked.

Finally, a separate note on the UnhandledException event: This is setup in DoApplicationModel by hooking into the Application.ThreadException event. DoApplicationModel can also raise the UnhandledException event as a result of an exception occurring around (effectively) Application.Run. We know that there are 3 actions one must take to catch all unhandled exceptions, instead here we see only two! So it is obvious that the AppDomain.UnhandledException has to be separatelly subscribed to by the developer (for catching thread exceptions other than the GUI). I think this is a gotcha and the VB team should also hook into it so that when we catch the UnhandledException in MyEvents.vb we really are catching all unhandled exceptions.

Next time we'll look at the possibility of using this approach (including catching the events) from C#.

Class Designer - The Missing

Thu, August 26, 2004, 10:30 AM under Whidbey | VisualStudio
UPDATED the status of the suggestions on ladybug

Previously in the overview of the Class Designer I focused on the good aspects.

I did not mention two tracking windows that I am not that excited about but you might be, so I'll briefly summarise them.

Each time a shape is selected/clicked in the diagram, there are two windows that get updated: Properties and Class Details (in my configuration on the bottom right and bottom respectively). Class Details is a breakdown of the elements in the shape for finer editing. However, I'd rather double click on the shape and go straight to code where the excellent code editor/intellisense will help me make my change, then Ctrl+TAB and I am back in the diagram. The Properties window shows info already on the diagram (e.g. method name, access modifier), it shows info that should be on the diagram (e.g. method signature, type, whether it is static) and it shows info that I wouldn't mind going to code to see (e.g. Custom Attributes, remarks, summary). I would probably be more enthusiastic about these windows if I didn't know that the development time taken to offer us these could have been used to plug more essential gaps that are there due to "resource constraints".

Talking of gaps in functionality here is a list of features that would greatly improve the tool. They are over at the MSDN Feedback center as suggestions where the problem and proposed solution for each are described.

1 (POSTPONED) Show Full method signature for methods, events, delegates, overloads
(a must have feature whose ommission makes the whole Class Designer almost useless IMHO)

2 (POSTPONED) Support a dependency association
(read my justification for this... it is one of the least appreciated yet most useful of UML IMO)

3 (POSTPONED) Static members should have visual indication on diagram

4 (POSTPONED) Visual distinction of readonly properties

5 (POSTPONED) Event as association and How to show subscription to an event

6 (FIXED) Delegate signature

7 (POSTPONED) Delegates (and other nested types) shown outside the class

8 (POSTPONED) Visual representation/distinction of Namespaces

9 (POSTPONED) Attach notes to classes and associations at least

10 (FIXED) "View in diagram" should not always create a new diagram

11 (POSTPONED) Navigation aid for large class diagram

12 (FIXED) "View in diagram" framework types from Object Browser

13 (POSTPONED) Option to use .NET framework types instead of language types

Class Designer - The Good

Wed, August 25, 2004, 11:05 AM under Whidbey | VisualStudio
So VS2005 brings with it a great feature: the Class Designer.

For those of you unfamiliar with UML, think of it as a diagrammatic compliment to the Object Browser and Class View.

If you are familiar with UML (and its 8-9 diagram types), think Class Diagram but MSFT are going their own way with a slightly different notation.

Classes (reference types) and interfaces are represented by rounded-corner box shapes, and Structures/enumerations (value types) are represented by square boxes. Abstract classes are shown with a dotted line. Each box has up to four sections: Fields, Properties, Methods and Events. This is a great improvement over UML, where you just have 2 sections for attributes and operations; representing anything else requires stereotypes and/or other custom mechanisms. Each member can individually be hidden. Furthermore, each section is collapsible, as is the class as a whole; from a usability point of view this is done easier than in any other tool I have used!

The other item available from the toolbox is a square yellow note for adding comments in free format. While on the subject of color, it is used as a further aid in distinguishing elements on the diagram: classes/structs are blue, delegates red, interfaces green and enums are violet (unless I have become color-blind :-)

Interface implementation is shown via the lollipop shape, and it's good to see just one of these coming out of a class with a list of all the interface names below it: this reduces clatter. Should you wish to view the member of each interface separately, this is just a context menu away: "Show Interface". Inheritance is represented by the UML closed arrow head. The only other relationship supported is open arrow head association (i.e. when a type references another type) and there is an excellent feature where a field/property can be visualised as an association or vice versa: "Show as Association". Naturally, if one of your classes contains a field of a framework type, then showing as association will show a class of the framework type...this is great for reverse engineering the .NET library classes.

The Class Designer is always in synch with your code. In case that was not clear, any change in the class diagram (e.g. adding a method, changing a field) is reflected in code and any change in the code (e.g. deleting a property, changing a delegate) is reflected on the diagram; there is no code generation/reverse engineering step; they are just "naturally" in synch. In fact, if you look at the file (with extension "cd") you will find an XML document with layout and file information, but nothing that describes the members of the types as they are all read via reflection every time the class diagram is displayed. Navigation between the two is easy: going from a diagram element to its code counterpart is a double-click away and at any point in a code file, one can "View in Diagram" the types declared in the file.

Did I mention that Class Designer not only is available for all languages but also for CF projects as well :-D

Next time we'll look at what is still missing...