Restrict type in a Collection inside a class module

后端 未结 4 1527
暖寄归人
暖寄归人 2020-12-16 06:36

I have a collection inside a class module. I\'d like to restrict the object type that is \"addable\" to this collection, i.e. collection should only ever accept objects of o

4条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-16 07:00

    This is what I did. I liked Rob van Gelder's example, as pointed to by @jtolle, but why should I be content with making a "custom collection class" that will only accept one specific object type (e.g. People), forever? As @jtolle points out, this is super annoying.

    Instead, I generalized the idea and made a new class called UniformCollection that can contain any data type -- as long as all items are of the same type in any given instance of UniformCollection.

    I added a private Variant that is a placeholder for the data type that a given instance of UniformCollection can contain.

    Private mvarPrototype As Variant
    

    After making an instance of UniformCollection and before using it, it must be initialized by specifying which data type it will contain.

    Public Sub Initialize(Prototype As Variant)
        If VarType(Prototype) = vbEmpty Or VarType(Prototype) = vbNull Then
            Err.Raise Number:=ERR__CANT_INITIALIZE, _
                Source:=TypeName(Me), _
                Description:=ErrorDescription(ERR__CANT_INITIALIZE) & _
                    TypeName(Prototype)
        End If
        ' Clear anything already in collection.
        Set mUniformCollection = New Collection
        If VarType(Prototype) = vbObject Or VarType(Prototype) = vbDataObject Then
            ' It's an object. Need Set.
            Set mvarPrototype = Prototype
        Else
            ' It's not an object.
            mvarPrototype = Prototype
        End If
        ' Collection will now accept only items of same type as Prototype.
    End Sub
    

    The Add method will then only accept new items that are of the same type as Prototype (be it an object or a primitive variable... haven't tested with UDTs yet).

    Public Sub Add(NewItem As Variant)
        If VarType(mvarPrototype) = vbEmpty Then
            Err.Raise Number:=ERR__NOT_INITIALIZED, _
                Source:=TypeName(Me), _
                Description:=ErrorDescription(ERR__NOT_INITIALIZED)
        ElseIf Not TypeName(NewItem) = TypeName(mvarPrototype) Then
            Err.Raise Number:=ERR__INVALID_TYPE, _
                Source:=TypeName(Me), _
                Description:=ErrorDescription(ERR__INVALID_TYPE) & _
                    TypeName(mvarPrototype) & "."
        Else
            ' Object is of correct type. Accept it.
            ' Do nothing.
        End If
    
        mUniformCollection.Add NewItem
    
    End Sub
    

    The rest is pretty much the same as in the example (plus some error handling). Too bad RvG didn't go the whole way! Even more too bad that Microsoft didn't include this kind of thing as a built-in feature...

提交回复
热议问题