Почему варианты Delphi не могут содержать объекты?

Почему варианты Delphi не могут содержать объекты? Что еще более важно, в чем причина этого ограничения?

14.12.2008 09:27:08
3 ОТВЕТА
РЕШЕНИЕ

Это просто мнение, исходя из моего опыта, что варианты могут и не могут сделать.

Если вы поместите в него COM-объект, он будет сохранен как ссылка IDispatch, и, таким образом, любые вызовы методов или свойства, к которым вы обращаетесь к этому объекту, будут преобразованы в некоторый код, который ищет внутренний DISPID метода / свойства, массив с аргументами метода, и метод будет вызываться через интерфейс IDispatch.

Другими словами, IDispatch обрабатывается для вас так, как вы обычно это делаете, но компилятор делает это автоматически.

Однако для обычных объектов Delphi все становится сложнее. Вы можете использовать RTTI для поиска и вызова опубликованных методов и свойств, но это все. Если у вас есть имя неопубликованного, не виртуального метода, Delphi не может найти правильный адрес для него в вашем методе.

Другими словами, все, что вы могли бы сделать, это просто удерживать объект, вы не сможете его использовать. Возможно, они могли бы добавить поддержку только для его освобождения, но, опять же, это, вероятно, было бы так.

Я точно знаю, что если вы правильно внедрили IDispatch, вы можете безопасно хранить и использовать объект через один из вариантов. У меня есть класс, который можно использовать в качестве базового класса для объектов Delphi, с которыми вы хотите это сделать. Он автоматически выставляет опубликованные методы / свойства, и вы можете добавить больше, если хотите, с помощью некоторых вызовов защищенных методов. Если есть интерес к такому классу, я могу разместить его где-нибудь.

Но опять же, это через IDispatch, и он использует опубликованные методы, остальное - ручной код, поэтому поддержка вариантов должна быть встроена в ваши объекты, вами.

Вот почему я думаю, что они просто сказали: это будет вызывать жалобы, что мы можем держать объект, но это просто бесполезно.

Но это только мои мысли. Возможно, у кого-то из чиновников гораздо лучший ответ.

8
14.12.2008 09:44:18
Вы в значительной степени правы. Также следует упомянуть классы TCustomVariantType и TInvokeableVariantType. Эти классы показывают все, что класс должен был бы сделать, чтобы его можно было использовать (а не просто хранить) в Variant без необходимости реализации IDispatch.
Rob Kennedy 14.12.2008 17:34:00
+1 к Робу: TCustomVariantType и TInvokeableVariantType довольно мощные. Некоторые потери производительности, но которые могут быть обойдены при некотором низкоуровневом взломе .
Arnaud Bouchez 10.10.2013 06:47:04

Вы определенно можете хранить объект внутри переменной Variant - просто приведите его в NativeUInt. Во всяком случае, объект - это просто указатель.

obj := TObject.Create;
v := NativeUInt(obj);
obj := TSomeObject(NativeUInt(v));
25
3.11.2011 21:11:06

Я использовал Variants для хранения объектов в прошлом, используя внутренние компоненты Variant, код выглядит примерно так:

var
  MyObject: TMyObject;
  Value: Variant;
begin
  MyObject:= TMyObject.Create;
  TVarData(Value).VType:= VarByRef or VarUnknown;
  TVarData(Value).VPointer:= MyObject;
7
23.03.2018 01:47:56
Обратите внимание, что вы обманываете. VarByRef - это флаг, предназначенный для изменения поля основного типа. Ваш код говорит, что переменная пуста , но она пуста по ссылке.
Rob Kennedy 14.12.2008 17:29:40
Концептуально это нормально, я думаю; логически, нетипизированная ссылка на местоположение эквивалентна нетипизированному указателю, т.е. void * в C или Pointer в Delphi.
Barry Kelly 21.01.2009 06:13:03
Это должно быть varByRef or varVariantправильно работать в Delphi.
user2091150 6.04.2015 13:53:44
VarByRef - это флаг в старших четырех битах типа. Поскольку флаг VarByRef устанавливается сам по себе для типа, младшие двенадцать битов, которые содержат фактический тип, будут равны нулю, что для варианта означает целочисленный тип. Лучшая идея - установить тип в varByRef | varUnknown - действительно, это то, что это, указатель на тип, который неизвестен варианту.
Kurt Fitzner 12.01.2017 12:17:43