Newsgroup: it.comp.lang.delphi
Titolo: [D6] TypeCast classi derivate senza definizione di tipo

Salve,
ho una FList:TObjectList in cui inserisco degli oggetti cosi' definiti:
TCustomDerivato = class(TPersistent)
  published
	procedure SaveToFile; virtual;
end;
TDerivato = class(TCustomDerivato)
  published
	procedure SaveToFile; override;
end;
Premessa, La lista TObjectList non conosce TDerivato, ma solo
TCustomDerivato.
A questo punto vorrei poter fare una cosa del genere:
TCustomDerivato(FList.Items[0]).SaveToFile;
Il problema e' cosi' facendo accedo solamente all'implementazione di
TCustomDerivato e non anche a quella di TDerivato
Ho provato una soluzione del genere:
var
ASaveToFile:pointer;
begin
  ASaveToFile := FList.Items[tmp].MethodAddress('SaveToFile');
  if Assigned(ASaveToFile) then
    TProcedure(ASaveToFile);
end;
Ed effettivamente funziona, nel senso che facendo debug la chiamata
viene fatta correttamente e la procedura TDerivato.SaveToFile viene
eseguita. Univo problema e che cercando di accedere alle proprieta di
TCustomDerivato si inchioda e solleva una eccezione di access violation.
Che cosa posso fare?
Se stampo FList.Items[0].Classname (e ClassType) la classe e' TDerivato.
Non esiste una soluzione del tipo:
(FList.Items[0] as FList.Items[0].ClassType).SaveToFile;
Le funzioni RTTI mi potrebbero aiutare?
Grazie.
-- 
I'am what I'am, I do what I can

Il 10 Set 2003, 00:53, "Setec Astronomy" <setec@_NO_NOSPAM_freemail.it> ha
scritto:

Se ho ben capito qualcosa di analogo a ...
if ActiveControl is TEdit then TEdit(ActiveControl).SelectAll;
Var
  Oggetto : LaMiaClasse ; // precedentemente definita
...
Oggetto := FList.Items[0] ;
If Oggetto Is LaMiaClasse Then LaMiaClasse(Oggetto).Metodo ;
...
Spero ti sia utile.
Ciao.
--------------------------------
Inviato via 
http://usenet.libero.it

Io me lo verifico così.
....
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls,Forms, Dialogs;
Type
  tClasse = Class
  Campo : Integer ;
  Procedure SetCampo ( C : Integer ) ;
  Procedure GetCampo ;
  End ;
type
  TForm1 = class(TForm)
    procedure FormActivate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
implementation
{$R *.DFM}
Procedure tClasse.SetCampo ( C : Integer ) ;
Begin
  Self.Campo := C ;
End ;
Procedure tClasse.GetCampo ;
Begin
  ShowMessage (IntToStr(Self.Campo)) ;
End ;
procedure TForm1.FormActivate(Sender: TObject);
Var
  Ogg : tClasse ;
begin
  Ogg := tClasse.Create ;
  If Ogg Is tClasse Then tClasse(Ogg).SetCampo ( 1 ) ;
  If Ogg Is tClasse Then tClasse(Ogg).GetCampo ;
end;
end.
Ciao


 > TCustomDerivato.
Altrimenti e' un semplice type cast esplicito.
Saluti.



Open Delphi Manual (
http://groups.yahoo.com/group/delphi_open_manual/
)

 sarebbero da chiarire.
Per il momento sto provando con le interfacce, probabilmente riesco a
risolvere cos'.


 risolvere cos'.
Fai una prova con codice di esempio più snello, senza utilizzare le tue
classi...magari è solo un errore di distrazione che causa il
malfunzionamento.


 Perche' ho fatto delle prove con RTTI ma senza successo.
come dice va Marco Breveglieri il tutto mi sembra molto laborioso
Aggiungo risalire ad un metodo tramite il nome  non è propriamente
oop come del resto le RTTI che nel tuo caso non sò se possono esseti
utili ma le lascerei perdere.
Magari cerca di cambiare approccio forse una collection potresti risolere
mettendo come classe del collectionItem la tua superclasse e poi fare l'Add
a seconda
di determinate condizioni.
Oppure una Lista tipo i campi Fileds dei DataSet con un metodo
Add(Field: TField) nel tuo caso Add(CustomDerivato:TCustomDerivato).
e poi con una proprietà di tipo
property CustomDerivato[Index: Integer]: TCustomDerivato read
GetCustomDerivato write SetCustomDerivato;
Vedi un pò...
Ciao
  Gabriele

 TCustomDerivato(FList.Items[0]).SaveToFile;
Cioe' vuoi poter salvare un singolo Item per volta?
Ma perche' non subclassare TObjectList in modo che ritorni direttamente
il tipo (base) che ha tutto cio' che ti serve?
In questo modo puoi chiamare FList.Derivati[i].SaveToFile o anche
direttamente FDerivatiList[i].SaveToFile;
Normalmente faccio q.cosa di simile:
  TBaseSignal = class(TObject)
  private
    fOwner: TSignalList;
    ...
  protected
    ...
    procedure SaveToStrings(out dest: TStrings); virtual;
  public
    constructor Create(anOwner: TSignalList; anID: integer);
    procedure LoadFromStrings(const src: TStrings); virtual;
  end;
  TSignal = class(TBaseSignal)
  private
   ...
  public
   ... // override proper methods
  end;
  TSignalList = class(TObjectList)
  private
    fFilename: TFilename;
    ...
  protected
    function GetSignal(Index: integer): TBaseSignal;
    ...
    procedure LoadFromFile(const src: TFilename);
  public
    constructor Create(src: TFilename...);
    ...
    procedure LoadSignals;
    procedure SaveSignals;
    function Add(aSignal: TBaseSignal): integer;
    property Signals[Index: integer]: TBaseSignal read GetSignal;
default;
    ...
  end;
Saluti
Paolo Arosio