¿Por qué las variantes de Delphi no pueden contener objetos? Más importante aún, ¿cuál es el motivo de esta limitación?¿Por qué las variantes de Delphi no pueden contener objetos?
Respuesta
Esto es solo una opinión, por mi experiencia con lo que las variantes pueden y no pueden hacer.
Si coloca un objeto COM en él, se almacenará como una referencia de IDispatch, y así 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, se construirá una matriz con argumentos de método, y el método se invocará a través de la interfaz IDispatch.
En otras palabras, IDispatch se maneja para usted, de la forma 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 mantener el objeto, no podría ser capaz de 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 utilizar 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 sostener un objeto pero es inútil.
Pero eso es solo mi opinión. Quizás alguien oficial tenga una respuesta mucho mejor.
Definitivamente puede almacenar un objeto dentro de una variable de Variante - simplemente echarlo en un NativeUInt. Un objeto es solo un puntero, de todos modos.
obj := TObject.Create;
v := NativeUInt(obj);
obj := TSomeObject(NativeUInt(v));
que había utilizado variantes para sujetar objetos en el pasado el uso de los componentes internos variante, el código es algo como esto:
var
MyObject: TMyObject;
Value: Variant;
begin
MyObject:= TMyObject.Create;
TVarData(Value).VType:= VarByRef;
TVarData(Value).VPointer:= MyObject;
Tenga en cuenta que está haciendo trampa. VarByRef es una * bandera * destinada a modificar el campo de tipo subyacente. Su código dice que la variable está * vacía *, pero está vacía por referencia. –
Hmmm? Rob, ¿esto significa que varIsEmpty volvería True ??? –
Conceptualmente está bien, creo; lógicamente, una referencia sin tipo a una ubicación es equivalente a un puntero sin tipo, es decir, void * en C o Pointer en Delphi. –
- 1. ¿Por qué las interfaces C# no pueden contener campos?
- 2. ¿Por qué las cadenas no literales no pueden contener líneas nuevas?
- 3. ¿Por qué las uniones anónimas no pueden contener miembros con constructores/destructores no triviales?
- 4. interfaces no pueden contener campos
- 5. ¿Por qué las cadenas en $ _POST no pueden contener un punto "."?
- 6. Las etiquetas de servidor no pueden contener construcciones <% ... %>
- 7. Delphi - registros con partes variantes
- 8. ¿Qué elementos HTML no pueden contener nodos secundarios?
- 9. ¿Por qué Viewstate puede contener solo objetos serializables?
- 10. VB6: Deshabilitar las variantes
- 11. Cómo usar matrices de variantes en Delphi
- 12. ¿Pueden las matrices PHP contener elementos de tipos diferentes?
- 13. ¿Por qué las propiedades no pueden ser de solo lectura?
- 14. ¿Por qué los registros de Delphi no tienen herencia?
- 15. ¿Por qué las clases internas no pueden declarar miembros estáticos?
- 16. ¿Por qué no se pueden compartir las variables miembro?
- 17. ¿Por qué las enumeraciones no se pueden modificar?
- 18. ¿Por qué las estructuras no se pueden asignar directamente?
- 19. Las variantes se usan recursivamente?
- 20. ¿Por qué las DLL de Delphi pueden usar WideString sin usar ShareMem?
- 21. Java: ¿Pueden las interfaces contener variables constantes definidas en ellas?
- 22. ¿Cómo tratar con JSON y objetos variantes?
- 23. Los parámetros WCF REST no pueden contener puntos?
- 24. Por qué las funciones anidadas pueden acceder a variables desde funciones externas, pero no pueden modificarlas
- 25. ¿Cómo dividir csv cuyas columnas pueden contener,
- 26. ¿Por qué no se pueden serializar objetos y clases de casos?
- 27. ¿Por qué no se pueden sobrecargar las funciones por tipo de devolución?
- 28. ¿Por qué no se pueden inicializar campos no estáticos dentro de las estructuras?
- 29. ¿Por qué no se pueden crear objetos sin usar class-keyword?
- 30. DataSnap "Objetos antiguos de Delphi" y objetos anidados
que está bastante bien. También debe mencionar las clases TCustomVariantType y TInvokeableVariantType. Esas clases muestran todas las cosas que una clase tendría que hacer para poder * usar * (no solo almacenadas) en una Variante, sin implementar necesariamente IDispatch. –
+1 a Rob: TCustomVariantType y TInvokeableVariantType son bastante potentes. Algunas penalizaciones de rendimiento, pero que [se pueden eludir con alguna piratería de bajo nivel] (http://blog.synopse.info/post/2011/07/01/Faster-variant-late-binding). –