I have done some initial programming using the C++/CLI and have some comments about my experience.

I had an existing program which parsed VC 6.0 dsp files to extract a variety of settings and lists of files. As my company goes forward with converting to using the VC 2005, projects are being converted and now use the new vcproj files. I have updated this program to also support parsing the vcproj file. Until all projects are converted, I need to maintain support for dsp files and vcproj files. Since the existing project already does significant work in unmanaged code and there is a managed VCProjectEngineObject available which can load/parse the new files, I made a mixed mode project.

The first thing that I noticed is that although the VCProjectEngineObject is setup to load VC projects, all of the examples for using it are in VB. This seems to be a strange choice (especially for an object that accesses a vcproj file).

Is this a common practice to give code examples in just one language?
Are there any plans to enhance the documentation to provide examples in other languages?

I realize that the syntax changed from managed C++ to C++/CLI, so it may just take a while for the documentation to catch up. I can follow the examples given in VB, but sometimes it is nice to cut and paste an example in the language that I am working in.

The second thing is that I needed to use casts more than I would have expected. For example, the first thing I wanted to do after creating the VCProjectEngineObject was to load a project. The LoadProject member of the VCProjectEngine returns a System::Object^. I used code like this:

   using namespace Microsoft::VisualStudio::VCProjectEngine;

   VCProjectEngine^ engine = gcnew VCProjectEngineObject;
   VCProject^ project = safe_cast<VCProject^>( engine->LoadProject( filename) );
I would have thought that the LoadProject() member should return a VCProject^ instead of an Object^, as this is type that it is actually loading.

I haven’t looked at other objects yet to see if this is a common practice or is limited to just the VCProjectEngine.

Is it normal for interface routines to return a System::Object^ instead of a derived type (even though the actual object is really some derived object)?

I try to minimize the number of casts used in the code I write, but this is making me add casts where I wouldn’t expect. I am wondering whether I will see this in other .net objects.

Similarly, after the project is loaded, many of the members of the VCProject use Object^ as the type instead of the only type they can be (such as the Files member, which is used as an IVCCollection^, but is an Object^). This again makes me need to use a cast, but if the member type was specified differently, I wouldn’t need to cast. Some of the members are of type String^, which don’t need casts.

Is it normal for members of objects to use System::Object^ instead of a derived type?
Or is this just the VCProjectEngine and related objects that are using System::Object^ for members when they should really use a specific type?

I did use and like the “for each” support to loop through all the files in the collection – this removed the need for one cast as the variable type in the loop worked without the cast.

   IVCCollection^ Files = safe_cast<IVCCollection^>(project->Files);
   for each ( VCFile^ file in Files )
      // do something with file…
I didn’t find the C++/CLI interface to be difficult to use, but just felt that it sometimes makes me type more code than should be needed. This could just be due to the particular object I am using (VCProjectEngine).

I may not done everything using the best practices for C++/CLI – I am still learning and without examples in the C++/CLI language it can be difficult. It took some experimenting to find out how to use the engine to get at the parts that I was looking for.