Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

Ответ 2

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

obj := TObject.Create;
v := NativeUInt(obj);
obj := TSomeObject(NativeUInt(v));

Ответ 3

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

var
  MyObject: TMyObject;
  Value: Variant;
begin
  MyObject:= TMyObject.Create;
  TVarData(Value).VType:= VarByRef;
  TVarData(Value).VPointer:= MyObject;