Ver Mensaje Individual
  #7  
Antiguo 12-08-2006
Avatar de dec
dec dec is offline
Moderador
 
Registrado: dic 2004
Ubicación: Alcobendas, Madrid, España
Posts: 13.141
Reputación: 36
dec Tiene un aura espectaculardec Tiene un aura espectacular
Hola,

Cita:
Empezado por Lepe
Deriva de TComponent que ya tienes los métodos Assign.
"TPersintent" es la primera clase que cuenta con un método "Assing":

Cita:
Empezado por Ayuda de Delphi
TPersistent is the ancestor for all objects that have assignment and streaming capabilities.
Pero hay que seguir un poco más adelante, en la misma ayuda:

Cita:
Empezado por Ayuda de Delphi
TPersistent encapsulates the behavior common to all objects that can be assigned to other objects, and that can read and write their properties to and from a form file (.xfm or .dfm file). For this purpose TPersistent introduces methods that can be overridden to:

Define the procedure for loading and storing unpublished data to a stream.
Provide the means to assign values to properties.
Provide the means to assign the contents of one object to another.

Do not create instances of TPersistent. Use TPersistent as a base class when declaring objects that are not components, but that need to be saved to a stream or have their properties assigned to other objects.
Pero, hasta donde yo llego, cuando derives de "TComponent" no estás utilizando ningún método "Assing" de esta clase, porque la misma no cuenta con él (no lo sobreescribe), sino que se usa el método "Assing" de la clase "TPersintent", de la que hereda "TComponent".

Léase la ayuda del método "Assing" de "TPersistent", pero, vamos aquí a ver el código fuente de dicho método:

Código Delphi [-]
procedure TPersistent.Assign(Source: TPersistent);
begin
  if Source <> nil then Source.AssignTo(Self) else AssignError(nil);
end;

Es decir... (atreviéndome un poco y por lo que he entendido en la ayuda), se averigua primero si el objeto "origen" no es "nil", y, en caso de que no sea "nil" se llama al método "AssingTo" del propio objeto "origen". En caso contrario se produce un error.

Continuemos con el método "AssingTo", que se encuentra también la clase "TPersistent" declarado como un método protegido y virtual. ("Assing" está declarado como virtual también, pero es un método público). Este es el código fuente del método "AssingTo" de la clase "TPersistent":

Código Delphi [-]
procedure TPersistent.AssignTo(Dest: TPersistent);
begin
  Dest.AssignError(Self);
end;

No sé qué les parecerá a ustedes, pero, me parece que se está queriendo decir: "no debes llamar a este método desde un objeto "TPersistent", sino desde algún objeto que implemente este método virtual, más aún, no debes llamar a "AssingTo", directamente, sino que llama al método "Assing", que ya se encargará de llamarme a mí.".

Casi termino diciendo que no sabré dar una solución, como no sea por aproximación y según escribo esto, pero, si derivas un objeto de "TComponent", como si lo derivas de "TPersistent", no harás sino producir un error si llamas al método de dicho objeto "Assing", puesto ya hemos visto que "TPersistent" quiere (al declararlos como virtuales) que sean las clases derivadas de ella las que implementen los métodos "Assing" y "AssingTo".

Como "TComponent" no implementa dichos métodos virtuales, aunque deriva de "TPersistent", resulta que algo como esto deriva en una excepción de tipo "EConvertedError":

Código Delphi [-]
type
  TObjeto = class(TComponent)
  private
    FVariable: string;
  public
    property Propiedad: string read FVariable write FVariable;
  end;

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
var
  objeto, objeto2: TObjeto;
begin
  objeto := TObjeto.Create(Self);
  objeto.Propiedad := 'Una cadena';

  objeto2 := TObjeto.Create(Self);
  objeto2.Assign(objeto); // EConvertError

  objeto.Free; // Liberamos
  objeto2.Free;
end;

Código Delphi [-]
type
  TObjeto = class(TPersistent)
  private
    FVariable: string;
  public
    property Propiedad: string read FVariable write FVariable;
  end;

implementation

{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
var
  objeto, objeto2: TObjeto;
begin
  objeto := TObjeto.Create;
  objeto.Propiedad := 'Una cadena';

  objeto2 := TObjeto.Create(Self);
  objeto2.Assign(objeto); // EConvertError

  objeto.Free; // Liberamos
  objeto2.Free;
end;

¿Y entonces? ¿Cómo podemos clonar un objeto, duplicarlo o como lo queramos llamar? Pues a mí después de todo esto que he escrito para ver si me daba alguna idea, no me queda sino pensar en que los objetos a clonar deben implementar por su cuenta los métodos "Assing" y "AssingTo", y derivar de "TPersistent", directa o indirectamente.

Así que, no sé yo de qué objetos estamos hablando, pero, la clonación de un objeto a mí no me parece nada sencilla. Claro que yo de esto entiendo más bien poco, pero, si lo que he dicho tiene algún sentido, los objetos, las propiedades que fueran a su vez objetos, tendrían que contar con métodos "Assing" y "AssingTo", como digo, y además estaría aquello de tener que decidir entre las dos opciones que parece que hay, como poco:

Cita:
Empezado por De la ayuda de la interfaz ICloneable en la plataforma .NET
A shallow copy of a collection copies only the elements of the collection, whether they are reference types or value types, but it does not copy the objects that the references refer to. The references in the new collection point to the same objects that the references in the original collection point to.

In contrast, a deep copy of a collection copies the elements and everything directly or indirectly referenced by the elements.
O sea, que vais a tener que perdonarme el rollo que acabo de soltar, porque, desde luego no me atrevo, sin saber más del tema en concreto que tratamos (tipos de objetos, etc.) a dar una solución sencilla. Algún compañero quizás vea esto de otro modo menos embrollado que como yo lo veo.
__________________
David Esperalta
www.decsoftutils.com
Responder Con Cita