2

I'm trying develop an add-in for an application using it's API and I have Option Strict turned on. Trying to work with these COM objects is causing multiple compile issues saying

Option Strict On disallows implicit conversions from 'typeA' to 'typeB'.

I'm currently overcoming the issue by using DirectCast, which means I have to define the type in multiple places, which makes future code maintenance kind of sucky.


A simple example is:

Dim templateMgr As IEdmTemplateMgr5 = TheVault.CreateUtility(EdmUtility.EdmUtil_TemplateMgr)

The CreateUtility method returns an object which implements the interface specified by the argument (argument is an EdmUtility Enum value).

The return is specified at compile time as System.Object so must be cast to the right type in order to use it.

With option strict on I cannot do this implicitly, so I have been using DirectCast thusly:

Dim templateMgr As IEdmTemplateMgr5 = DirectCast(TheVault.CreateUtility(EdmUtility.EdmUtil_TemplateMgr), IEdmTemplateMgr5)

There are many, many, many (that many!) COM members that use generic members that make the compiler very unhappy with Option Strict turned on.

I don't particularly like using DirectCast() because it means declaring the type in multiple places scattered all throughout the code.

Is this a case where it's better to just turn off Option Strict??

I feel like there has to be a better way!


EDIT 1

My compile options are:

  • Option Explicit = ON
  • Option Strict = ON
  • Option Infer = ON
  • Option Compare = Text
  • Target CPU = AnyCPU

EDIT 2

Here is another example that isn't just creating a new object instance. In this example I am using a loop to get information on all the objects in an array that returned by another function.

The return from Data.Get is always type System.Object which again causes teh compiler to complain that implicit conversion from type 'Object' to type 'String' is not allowed with Option Strict on.

Dim DataReturn As System.Array
Dim refreshFlag As Long
Try
    refreshFlag = TheTemplate.RunEx(TheCommand.mlParentWnd, TheVault.RootFolderID, DataReturn)

    If Not DataReturn.IsAllocated Then Throw New Exception("Nothing was created by the template.")

    'Refresh the folder view if required
    If refreshFlag = EdmRefreshFlag.EdmRefresh_FileList Then TheVault.RefreshFolder(TheVault.RootFolderPath)

    'Return the path(s) of the newly created file(s)
    Dim path As String = String.Empty
    For Each data As EdmData In DataReturn
        Select Case data.Type
            Case EdmDataType.EdmData_File
                path = DirectCast(data.Get(EdmDataPropertyType.EdmProp_Path), System.String)
                If path.Length > 0 Then CreatedFilesPaths.Add(path)
                path = String.Empty
        End Select
    Next
CBRF23
  • 269

2 Answers2

2

Dealing with COM onjects is almost the canonical reason for setting Option Strict to off, or using the C# equivalent dynamic.

Late binding means that you loose the help of the compiler in getting things right, if you are fighting the compiler more than it is helping you, it is quite reasonable to just say "I know what I am doing".

I would recommend isolating these functions into a seperate file, and leave option strict on for everything else.

jmoreno
  • 11,238
1

Given that you are using Option Infer On, you could create a few generic extension methods to handle your situation.

Module EX
   <Extension()> _
   Public Function CreateInstance(Of T)(ByVal Vault7Instance As IEdmVault7, ByVal typ As EdmUtility) As T
      Return DirectCast(Vault7Instance.CreateUtility(typ), T)
   End Function
End Module

then instantiate something like this:

Dim templateMgr = TheVault.CreateInstance(Of IEdmTemplateMgr5)(EdmUtility.EdmUtil_TemplateMgr)