Я пытаюсь создать класс с несколькими свойствами, которые индексируются тем же номером, который я передаю в свойство. Я пробовал несколько конфигураций кода, моя последняя ошибка заключалась в следующем:
'dataTypeClass class module
Private ap() As String
Private dt() As String
Public Property Get apos(index As Long) As Variant
Set apos = ap(index)
End Property
Public Property Get dataType(index As Long) As Variant
Set dataType = dt(index)
End Property
Public Property Let apos(index As Long, apVal As String)
ap(index) = apVal
End Property
Public Property Let dataType(index As Long, dtVal As String)
dt(index) = dtVal
End Property
В основном я получаю этот код ошибки:
Ожидается использование ниже, чтобы получить "INT" и "" для пункта 1 в подпункте ниже.
Sub classTest()
Dim d As New dataTypeClass
d(1).dataType = "INT"
d(1).apos = ""
Debug.Print d(1).dataType & d(1).apos
End Sub
Что я делаю неправильно?
Обновлено:
Принимая приведенные ниже предложения (например, редактируя свой вопрос, а не комментируя), я устанавливаю варианты в виде строк и использую let вместо set. Поскольку я действительно получил индекс вне допустимого диапазона, мне нужно инициализировать класс, но нужен ли мне redim index? Как я могу это сделать, если каждый раз при запуске скрипта индекс будет иметь другой максимум?
Также указано в комментарии ниже, но d(1).dataType и d(1).apos должны быть d.dataType(1) и d.apos(1).
RE: Ваше последнее редактирование - это полностью зависит от вашей реализации. Здесь никто не знает, как вы собираетесь использовать этот класс и для чего он нужен. Но если вы не знаете, сколько элементов вам понадобится, рассмотрите возможность инкапсуляции Collection вместо массива.
@JohnyL, это правда, но совершенно не имеет отношения к этому вопросу и еще больше сбивает с толку ОП.
@JohnyL попробуйте public string Foo { get { return _foo; } int set { _foo = value; } } на C#, расскажите, как это происходит.
Синтаксическая ошибка @MathieuGuindon
@JohnyL IKR! Перегрузка методов тоже не любит конфликтующих типов! Вы не можете иметь int Foo() { return 42; } и string Foo() { return "42"; } и вызывать эту перегрузку метода.
@MathieuGuindon Я не понял, что вы пытались сказать, но я только что понял, что моя заметка о перегрузке не имеет ничего общего с вопросом. ))


У вас есть вариант для возвращаемого типа вашего Get, но ваш дополнительный параметр Let использует строку. Может вам нужен dtVal As Variant? Как упоминалось в комментариях и другом ответе, есть дополнительные вещи, которые следует учитывать; некоторые будут зависеть от реализации.
The parameters for Property Get, Property Let, and Property Setprocedures for the sameproperty must match exactly, except that the Property Let has one extra parameter, whose type must match the return type of the corresponding Property Get, and the Property Set has one more parameter than the corresponding Property Get, whose type is either Variant, Object, a class name, or an object library type specified in an object library. This error has the following causes and solutions:
The number of parameters for the Property Get procedure isn't one less than the number of parameters for the matching Property Let or Property Set procedure. Add a parameter to Property Let or Property Set or remove a parameter from Property Get, as appropriate.
The parameter types of Property Get must exactly match the corresponding parameters of Property Let or Property Set, except for the extra Property Set parameter. Modify the parameter declarations in the corresponding procedure definitions so they are appropriately matched.
The parameter type of the extra parameter of the Property Let must match the return type of the corresponding Property Get procedure. Modify either the extra parameter declaration in the Property Let or the return type of the corresponding Property Get so they are appropriately matched.
The parameter type of the extra parameter of the Property Set can differ from the return type of the corresponding Property Get, but it must be either a Variant, Object, class name, or a validobject library type.
Make sure the extra parameter of the Property Set procedure is either a Variant, Object, class name, or object library type.
You defined a Property procedure with an Optional or a ParamArray parameter. ParamArray and Optional parameters aren't permitted in Property procedures. Redefine the procedures without using thesekeywords.
Также необходимо избавиться от Set в Set apos = ap(index) и Set dataType = dt(index).
Это Private ap() As String и Private dt() As String (не As Variant), поэтому я предполагаю, что тип возврата Property Get должен быть As String, верно?
Также понадобится помощь с этими нераспределенными массивами и classTest. d(1).dataType предположительно должен быть d.dataType(1) = "INT", но выдает нижний индекс за пределы допустимого диапазона ...
Да ... спасибо. Я заметил несколько вещей, в том числе проблему использования set as is. Но, к счастью, мы с Мэттом также занимаемся этим делом!
Я тоже. Ржу не могу. :-)
Свойство apos1 получает Variant по указанному index; реализация предполагает, что инкапсулированный ap(index) - это Object, поэтому тип возврата, вероятно, должен быть Object вместо Variant:
Public Property Get apos(index As Long) As Variant
Set apos = ap(index)
End Property
Установщик использует назначение Let, что является хакерским, но разрешено, учитывая значение Variant - о, подождите, нет, это String!
Public Property Let apos(index As Long, apVal As String)
ap(index) = apVal
End Property
Вы получаете эту ошибку, потому что, как указано в ошибке, определение свойства несовместимо. Если ap(index) - это String, то получатель должен выглядеть так:
Public Property Get apos(index As Long) As String
apos = ap(index)
End Property
Если ap(index) - это Object, то сеттер должен выглядеть так:
Public Property Set apos(index As Long, apVal As Object)
Set ap(index) = apVal
End Property
... и получатель вроде этого:
Public Property Get apos(index As Long) As Object
Set apos = ap(index)
End Property
Или вот так:
Public Property Get apos(index As Long) As Variant
Set apos = ap(index)
End Property
Public Property Set apos(index As Long, apVal As Variant)
Set ap(index) = apVal
End Property
Другими словами:
Property Let / Property Set должен быть того же типа, что и тип возвращаемого значения одноименного члена Property Get.Property Set для назначений.Property Let для назначений.Variant.Set для назначения чего-либо, кроме ссылки на объект.1 Все это верно и для свойства dataType.
Когда я увидел название этого вопроса, я подумал про себя: «Ой, смотри, он играет песню Мэтта». Хорошая шапка.
BigBen поднимает хороший вопрос: ваши массивы не инициализируются, поэтому присвоение индексу приведет к ошибке 9 / index out of bounds - если вы просто не пропустили обработчик
Class_Initialize, который их инициализирует.