Это то, что я сделал.Мне понравился пример Роба ван Гелдера, на который указывает @jtolle, но почему я должен довольствоваться созданием "пользовательского класса коллекции", который будет всегда принимать только один конкретный тип объекта (например, People
), навсегда?Как отмечает @jtolle, это очень раздражает.
Вместо этого я обобщил идею и создал новый класс с именем UniformCollection
, который может содержать любой тип данных - при условии, что все элементы одного типа в любом данном экземпляре UniformCollection
.
Я добавил частный вариант, который является заполнителем для типа данных, который может содержать данный экземпляр UniformCollection
.
Private mvarPrototype As Variant
После создания экземпляра UniformCollection
и перед его использованием его необходимо инициализировать, указав, какой тип данных он будет содержать.
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
Затем метод Add будет принимать только новые элементы того же типа, что и Prototype (будь то объект или примитивная переменная ... еще не проверенные с UDT).
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
Все остальное примерно так же, как в примере (плюс некоторая обработка ошибок).Жаль, что RvG не прошел весь путь!Еще хуже, что Microsoft не включила подобные вещи в качестве встроенной функции ...