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
  • For local objects, have you tried option infer? Dim templateMgr = DirectCast(TheVault.CreateUtility... – Ňɏssa Pøngjǣrdenlarp Jun 30 '15 at 19:48
  • I should have mentioned, Option Infer is on. I'll edit my question to add the compile options. Thanks! – CBRF23 Jun 30 '15 at 19:49
  • 2
    Does not have anything to do with "base classes", COM does not support inheritance. Everything to do with late binding, keeps the customer happy. Well, the bean counter, not the programmer. Option Strict Off was made for this. – Hans Passant Jun 30 '15 at 20:15
  • 1
    Option Strict is not an all or nothing proposition. You can demote late binding or implicit conversion errors to warnings or to nothing at all and leave function return checks alone. See "warning configuration* on the compile tab. – Ňɏssa Pøngjǣrdenlarp Jun 30 '15 at 20:35
  • 1
    Migrating as requested by the author... – Shog9 Jul 17 '15 at 14:41
3

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.

0

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)
  • that sounds like it could work - but holy cow that is a lot of work for this project! whew! I think I'll wait and see if any other answers roll-in before doing all that ;) – CBRF23 Jun 30 '15 at 21:00
  • @CBRF23 that isnt all that much "wordy" that DirectCast – Ňɏssa Pøngjǣrdenlarp Jul 1 '15 at 0:44
  • @Plutonix - not sure what you mean by "wordy". I was saying it would be a lot of work to create an extension for every member that I have to use that requires a type conversion. – CBRF23 Jul 1 '15 at 13:30
  • that extension is generic: (Of T)...As T you pass which Type you want/need the new object cast as. One size fits all – Ňɏssa Pøngjǣrdenlarp Jul 1 '15 at 13:34
  • I see. But it looks like that would only be useful at initial instantiation. Maybe not so much in a loop like this? – CBRF23 Jul 1 '15 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.