delphi oop variant

¿Por qué las variantes de Delphi no pueden contener objetos?



oop (3)

Yo había usado variantes para retener objetos en el pasado usando las variables internas de Variant, el código es algo como esto:

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

¿Por qué las variantes de Delphi no pueden contener objetos? Más importante aún, ¿cuál es el motivo de esta limitación?


Esta es solo una opinión, según mi experiencia con qué variantes pueden y no pueden hacer.

Si coloca un objeto COM en él, se almacenará como una referencia IDispatch, y por lo tanto, cualquier llamada de método o propiedades a las que acceda en este objeto se convertirán en algún código que busque el DISPID interno del método / propiedad, una matriz con los argumentos del método se construirá, y el método se invocará a través de la interfaz IDispatch.

En otras palabras, IDispatch se maneja para usted, de la forma en que normalmente debería hacerlo, pero lo hace automágicamente el compilador.

Sin embargo, para objetos Delphi normales, las cosas se ponen más difíciles. Puede usar RTTI para encontrar y llamar a los métodos y propiedades publicados, pero eso es todo. Si tiene el nombre de un método no publicado y no virtual, Delphi no puede encontrar la dirección correcta para él en su método.

En otras palabras, todo lo que podría hacer sería simplemente sostener el objeto, no podría usarlo. Tal vez podrían agregar soporte para simplemente liberarlo, pero de nuevo, eso probablemente sea.

Sé con certeza que si implementa IDispatch correctamente, puede almacenar de forma segura y usar el objeto a través de una variante. Tengo una clase que se puede usar como clase base para los objetos Delphi en los que quieres hacer esto. Expondrá automáticamente los métodos / propiedades publicados, y puede agregar más si lo desea a través de algunas llamadas a métodos protegidos. Si hay interés en dicha clase, puedo ubicarla en algún lugar.

Pero, una vez más, esto es a través de IDispatch, y utiliza los métodos publicados, el resto es código manual, por lo que el soporte para las variantes tiene que ser incorporado en sus objetos por usted.

Por eso creo que acaban de decir: esto solo generará quejas, que podemos contener un objeto, pero es inútil.

Pero eso son solo mis pensamientos. Quizás alguien oficial tenga una respuesta mucho mejor.


Definitivamente puede almacenar un objeto dentro de una variable Variant, simplemente transfiéralo a NativeUInt. Un objeto es solo un puntero, de todos modos.

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