Tag Archive for VB

VB.NET and Enums

I’ve run into several problems with the way the VB.NET compiler handles enums.

I’ve described one here, a while ago. In a nutshell, an enum exposed by SPS was based on the non-CLSCompliant UInt32 datatype, and VB.NET was choking on it during compilation.

The second one I ran into recently was when using the Enterprise Library to access an Oracle database. I was trying to create a paramater for an OracleCommandWrapper object. The AddParameter method has the following overloads:

AddParameter(String Name, System.Data.DbType type, …)
AddParameter(String Name, System.Data.Oracle.OracleType type, …)

Both overloads accept an enum as the second parameter, and the rest of the arguments are identical. Both enums are based on Int32. When compiling a call to this method, I got a compiler errors saying that no accessible overload was available without a narrowing conversion.

I’m still not entirely sure what this compiler error meant. My suspicion is that since both enums are ultimately the same datatype, it cannot determine which overload to call. I would be glad to know exactly what it means.

The solution for both problems, however, was identical and involved mostly confusing the VB.NET compiler with shiny lights:

Instead of calling AddParameter(“Name”, OracleType.Cursor, …), I called it like this: AddParameter(“Name”, [Enum].Parse(GetType(OracleType), OracleType.Cursor.ToString()), …).

In effect, I print out the enum value as a string and then re-parse it into an enum. This trick seems to convince the compiler that everything is fine, and it compiles (and runs) smoothly. A simple CType() cast does NOT work. This solution also worked for the UInt32 enum in SPS – the compiler complained that it didn’t know what UInt32 was, but once I’ve perpetrated my little deception, everything was cool.

Anyone more familiar with the VB.NET compiler and can explain this behavior?

VB Build Events

Having found myself developing in VB.NET alongside C# recently, I was rather annoyed at the lack of pre- and post-build-events for VB projects in VS.NET2003.

A quick check of the DTE automation model showed that while the .VBPROJ file schema does not enable persistently storing build event information for VB projects, the EnvDTE.Project object DOES enable you to specify that property, whether it’s a C# or VB project – they just won’t be persisted to the VBProj file.

Inspired by Roy‘s recent Add-In contest, I decided to write a plug-in that persisted the build events to custom user properties in the project file and then reloads them into the PostBuildEvents on project load. A quick googling, however, revealed that I am, alas, too late. Microsoft themselves have released this add-in as part of their Automation Samples for extending Visual Studio.

I shall but link, and grieve.

PortalRight – all wrong.

A followup to this post:

The PortalRight enumeration defined in Microsoft.Sharepoint.Portal.Security is, for some reason, derived from UInt32 rather than Int32. You can see this in the Object Browser when in a VB.NET project.
This anomaly – nothing more than a raised eyebrow in a C# project – seems to be crippling in a VB.NET project.
Whenever I try to use this enum in code, the compiler claims that it can’t cast from Integer to PortalRight – even I always use the enum:

Dim acc as AreaAccessControl = new AreaAccessControl(ctx, PortalRight.ViewArea, myArea.ID)

Gives a compiler error in VB.NET, but works fine in C# – even though the second parameter is defined as PortalRight.
Casting it to UInt32 simply gives a “Can’t convert UInt32 to PortalRight”.
The only way I could get it to compile (didn’t check if it worked) is by doing Enum.Parse on PortalRight.ViewArea.ToString(), which is just SO wrong.

Anyone know why this is so?

To CLS or not to CLS.

For some reason, Sharepoint’s object model doesnt adher to Microsoft’s recommended practices – namely, trying to keep your external interfaces CLS-compliant.

It seems the object model itself exposes several methods and properties that use the UInt32 data-type, even if the SDK claims otherwise.