Delphi: передать TObject в массиве вариантов
У меня есть процедура, которая ожидает параметр типа TObject, что-то вроде этого:
MyProcedure (const AValue : TObject);
У меня есть массив Variant, который я перебираю для вызова процедуры, что-то вроде этого:
for i:=0 to High(myArray) do
MyProcedure (myArray[i]);
Компилятор выдает ошибку: "Несовместимые типы: TObject и Variant".
Что я могу сделать, чтобы обойти это?
Дополнительная информация: до сих пор я передавал простые типы (строки, числа, даты) в различных массивах (массивы обычно представляют собой смесь разных типов - в конечном итоге я передаю их как параметры в хранимую процедуру базы данных). Теперь мне нужно также (в некоторых случаях) передать объект TObject.
Каков наиболее подходящий тип данных / структура для передачи значений, которые могут содержать как простые типы, так и объекты? Я думаю, я мог бы создать свой собственный тип TParam, который имеет поле для обоих, но я не уверен в точном синтаксисе. У кого-нибудь есть пример этого?
4 ответа
Вариант не может содержать объекты, он может содержать только примитивные типы, такие как целое число и строка.
Я бы посоветовал изменить ваш массив на нужный вам тип, а не вариант. Если вы не уверены в желаемом типе объекта, создайте массив TObject или минимально возможный базовый класс объектов, которые будет содержать ваш массив.
Вы не можете хранить простые объекты, это вариант. Но вы можете хранить интерфейсы.
var
v : Variant;
i : IInterface;
begin
v := i; // Works perfectly;
end.
Посмотрите на типы для варианта:
varEmpty = $0000; { vt_empty 0 }
varNull = $0001; { vt_null 1 }
varSmallint = $0002; { vt_i2 2 }
varInteger = $0003; { vt_i4 3 }
varSingle = $0004; { vt_r4 4 }
varDouble = $0005; { vt_r8 5 }
varCurrency = $0006; { vt_cy 6 }
varDate = $0007; { vt_date 7 }
varOleStr = $0008; { vt_bstr 8 }
varDispatch = $0009; { vt_dispatch 9 }
varError = $000A; { vt_error 10 }
varBoolean = $000B; { vt_bool 11 }
varVariant = $000C; { vt_variant 12 }
varUnknown = $000D; { vt_unknown 13 }
//varDecimal = $000E; { vt_decimal 14 } {UNSUPPORTED as of v6.x code base}
//varUndef0F = $000F; { undefined 15 } {UNSUPPORTED per Microsoft}
varShortInt = $0010; { vt_i1 16 }
varByte = $0011; { vt_ui1 17 }
varWord = $0012; { vt_ui2 18 }
varLongWord = $0013; { vt_ui4 19 }
varInt64 = $0014; { vt_i8 20 }
varUInt64 = $0015; { vt_ui8 21 }
Если вы действительно хотите, приведите TObject к Pointer к Integer и сохраните его. Но я не уверен, действительно ли ты этого хочешь.
Моя первая реакция - спросить, почему вы храните объекты TObject в списке вариантов, но при условии, что у вас есть веская причина!
Если вам сначала удалось поместить свой экземпляр TObject в массив, тогда вы, вероятно, поместили указатель на объект Tobject. В этом случае вам нужно ввести тип Variant/Integer как объект TO, например:
for i:=0 to High(myArray) do
MyProcedure (TObject(myArray[i]));
Это должно сработать, однако, как и при любой типизации, вы должны убедиться, что myArray[i] фактически является указателем на экземпляр TObject, иначе могут произойти ужасные вещи.
Вы уверены, что TList не будет делать то, что вы хотите. Вариант действительно предназначен для хранения фундаментальных типов, таких как string, integer, float, boolean not Object.
Я не думаю, что это хорошая идея - создать TParam с переменной Variant и переменной TOBject. Что-то вроде:
Tobject = record
prim: Variant;
obj: TObject;
end
Работало бы, но мне это кажется очень грязным. Паскаль не типизированный язык, и я не буду относиться к нему как к одному. Я бы предложил либо:
Создайте еще одну функцию для обработки Variant, а также
MyProcedure (const AValue : TObject);
Также есть
MyProcedure (const AValue : Variant);
и обрабатывать ваши данные отдельно. Или создайте запись, которая определяет ваши входные данные, например, вместо того, чтобы у TParam варианта и объекта было что-то вроде:
TStoredProcParm = record
name: String;
bought: TDateTime;
end;
и так далее. Может быть, у вас так много разных данных, что маршрут варианта / объекта является лучшим, но это выглядит как головная боль при обслуживании - когда ваш другой код проходит массив Variant, откуда вы знаете, какой вариант, какой и как использовать каждый из них в вашем сохраненном процессе?