Previous | Index | Next 

[PRB] Compilation error when implementing an interface that defines a collection class

Note: this article only applies to conversions to VB.NET.

Let’s say that ICollection is a VB6 class that defines the interface of an enumerable collection, usually consisting of the four members Item, Count, and NewEnum:

        '## ClassRenderMode Interface

        Public Property Get Item(ByVal index As Variant) As Widget
        End Property

        Public Function NewEnum() As stdole.IUnknown
        End Function

        Public Property Get Count() As Long
        End Property

VB Migration Partner correctly converts this code to VB.NET:

        <VB6Object("MyProject.ICollection")> _
        Public Interface ICollection
            <System.Runtime.InteropServices.DispId(0)> _
            Default ReadOnly Property Item(ByVal index As Object) As Widget
            <System.Runtime.InteropServices.DispId(-4)> _
            Function NewEnum() As IEnumerator
            ReadOnly Property Count() As Integer
        End Interface

The problem with previous code is that the ICollection interface can’t really define a collectionclass-like interface, because all .NET collection classes must implement the Collection.IEnumerable interface. You must therefore force VB Migration Partner to generate a proper Inherits clause, which you do by adding the following pragma inside the VB6 code:

        '## PostProcess "Public Interface \w+", "$0\n\tInherits IEnumerable"

The generated code now becomes:

        ' VB.NET
        <VB6Object("MyProject.ICollection")> _
        Public Interface ICollection
            Inherits IEnumerable
			
            <System.Runtime.InteropServices.DispId(0)> _
            Default ReadOnly Property Item(ByVal index As Object) As Widget
            <System.Runtime.InteropServices.DispId(-4)> _
            Function NewEnum() As IEnumerator
            ReadOnly Property Count() As Integer
        End Interface

So far so good. Next, let’s say that you have a VB6 class named Widgets that implements the ICollection interface.

        Implements ICollection

        Private colObjs As New Collection

        Friend Property Get ICollection_Item(ByVal index As Variant) As Widget
            Set ICollection_Item = colObjs(index)
        End Property
  
        Friend Function ICollection_NewEnum() As stdole.IUnknown
            Set ICollection_NewEnum = colObjs.[_NewEnum]
        End Function
  
        Friend Property Get ICollection_Count() As Long
            ICollection_Count = colObjs.Count
        End Property

Here’s the code that VB Migration Partner generates for this class:

        <VB6Object("MyProject.Widgets")> _
        Public Class Widgets
            Implements ICollection
			
            Private colObjs As New Collection
			
            Friend ReadOnly Property ICollection_Item(ByVal index As Object) As Widget _
                       Implements ICollection.Item
                Get
                    Return colObjs.Item(index)
                End Get
            End Property
			
            Friend Function ICollection_NewEnum() As Object Implements ICollection.NewEnum
                Return colObjs.GetEnumerator()
            End Function

            Friend ReadOnly Property ICollection_Count() As Integer Implements ICollection.Count
                Get
                    Return colObjs.Count
                End Get
            End Property
        End Class

The previous code suffers from two problems, both of which cause a compilation error. First, VB Migration Partner converts the stdole.IUnknown type to Object rather than to IEnumerator. Second, the NewEnum function must implement also the IEnumerable.GetEnumerator member.

It’s easy, however, to fix this problem by means of a PostProcess pragma:

        '## project:PostProcess "_NewEnum\(\) As Object Implements ", 
            "_NewEnum() As IEnumerator Implements IEnumerable.GetEnumerator, " 

which caused the following code to be generated for the NewEnum method:

        Friend Function ICollection_NewEnum() As IEnumerator _
                    Implements IEnumerable.GetEnumerator, ICollection.NewEnum
            Return colObjs.GetEnumerator()
        End Function

 

Previous | Index | Next