Newsgroup: it.comp.lang.delphi
Titolo: Domanda su property.

Ciao a tutti,
stavo dando una lettura su: 
http://www.delphibasics.co.uk/RTL.asp?Name=Property
  riguardo a: Property.
Ora ammetto che mi sono confuso un po.
Brevemente, io ho definito un oggetto, in questo oggetto devo impostare dei 
valori di default e al tempo stesso devo permettere all'utente di poterli 
variare in qualsiasi momento.
IL problema è che non ho capito bene in che modo devo impostare la 
proprietà:  "Property" in senso sintattico intendo.
L'oggetto è definito ad esempio in questo modo:
  Type   MioOggetto = Class (TObject)
                      Private
                        Const MaxLen = 255;    // Lunghezza Massima Stringa
                      Public
                        Constructor Create;
                        Function MiaProcedura (Source: String): String;
                      End;
Ora in questo modo, io imposto come costante MaxLen ad un valore di default; 
ma devo permettere anche all'utente di poter variare il valore di MaxLen.
La proprietà Property credo sia la soluzione al problema, ma non ho capito 
in buona sostanza come usarla in modo sintatticamente corretta nel caso 
specifico.
Grazie in anticipo a chi mi risponde.
 

 Ora ammetto che mi sono confuso un po.
vai su Google e digita "Delphi property"
Cazzo, ma ci vuole tanto??
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it


Modera i toni per favore! Non è da persone civili usare questo linguaggio o 
forse ti definisci incivile? Fai tu.
Ciò premesso, ho cercato su google esattamente con quelle due parole chiavi 
e sono arrivato al sito di cui ho citato nel post precedente.
Il motivo per cui ho chiesto in questa sede è che il contenuto della pagina 
associata a quel link per quanto completo e tutto, mi ha creato qualche 
disorientamento (può succedere, nessuno è perfetto, e tutti siamo umani... 
forse tu sei una voce fuori dal coro? Nessun problema... affari tuoi 
sicuramente) ragion per cui ho chiesto di essere meglio orientato.
In un paese civile domandare è sempre lecito, rispondere è solo cortesia; 
ragion per cui invito gli incivili ad astenersi dal rispondermi e invito le 
persone educate, qualora lo desiderino di darmi una dritta.
Grazie in anticipo (alle persone educate e civili).
 

Ciao a tutti,
cercando di comprendere meglio le informazioni reperite su internet, ho 
provato a impostare il codice nel modo seguente:
  Type   MioOggetto = Class (TObject)
                      Private
                        Const MaxLen = 255;    // Lunghezza Massima Stringa
                        Function GetStrLen: Integer;
                        Function SetStrLen (Len: Integer): Integer;
                      Public
                        Constructor Create;
                        Function MiaProcedura (Source: String): String;
                        Property StrLen: Integer Read GetStrLen Write 
SetStrLen default 3;
                      End;
  Function MioOggetto.GetStrLen: Integer;
    Begin
      Result := StrLen;
    End;
  Function MioOggetto.SetStrLen (Len: Integer): Integer;
    Begin
      StrLen := Len;
    End;
Ora non so se ho fatto nel modo giusto, e vorrei un riscontro da parte 
vostra ed eventualmente essere corretto, però nel momento in cui provo ad 
avviare mi viene restituito sulla riga del property il seguente errore:
   [Pascal Error] MioFile.pas(16): E2008 Incompatible types
Dopo il Default segue un valore ordinale, ma non ho capito come correggere 
l'errore; ovvero non capisco l'incompatibilità dei tipi.
Il mio obiettivo è poter leggere dalla variabile StrLen il suo valore o 
aggiornarlo (scriverne uno nuovo) partendo da un valore di default impostato 
a 3.
Ringrazio chi può aiutarmi a risolvere il problema o indicarmi almeno la 
strada giusta.
Cooper. 

Cooper ha scritto:

Be' puoi fare in vari modi... iniziamo per gradi:
Metodo idiota:
Dichiari MaxLen come variabile e lo inserisci nella parte public
Pro: Facilissimo da implementare
Contro: Nessun controllo sull'assegnazione
Metodo Classico:
Dichiari due funzioni GetValue e SetValue nella parte public che si 
occupano di prelevare il contenuto di maxlen o di inserirlo
Pro: Controllo di errori
Contro: Difficile da ricordare
Metodo con "property":
Dichiari le funzioni come per il metodo classico ma, in oltre, dichiari 
una property con un nome univoco di tipo uguale alla variabile che usi e 
che fa riferimento alle funzioni GetValue e SetValue per leggere o 
inserire i dati
Pro: Controllo di errori e facilissimo per l'utente o per l'uso dato 
che, dall'esterno, si vede solo una variabile
Contro: non li ho ancora trovati.
Questo e' un esempio con le property relativo al pezzo di codice che hai 
inserito tu:
Type   MioOggetto = Class (TObject)
                     Private
                      Const MaxLen = 255;    // Lunghezza Massima Stringa
		     Function GetValue : Integer;
                      Procedure SetValue(Value : Integer);	
                     Public
                      Constructor Create;
                      Function MiaProcedura (Source: String): String;
                      Property MassimaLunghezza : Integer Read GetValue 
Write SetValue;
        End;
Ora, dall'esterno, per settare il valore di MaxValue basta usare 
Oggetto.MassimaLunghezza := Valore e, per leggerlo A := 
Oggetto.MassimaLunghezza
Quello che non si vede dall'esterno e' che la chiamata 
Oggetto.MassimaLunghezza := Valore non sarebbe altro che 
Oggetto.SetValue(Valore) metre la chiamata A := Oggetto.MassimaLunghezza 
si tradurrebbe in A := Oggetto.GetValue (sempre che le funzioni getvalue 
e setvalue siano state dichiarate nella sezione public)
Altre considerazioni:
Per inserire un valore di default aggiungere la dicitura DEFAULT 
<valore> alla fine della dichiarazione delle property e, in questo caso, 
inserire l'assegnazione di default nella Create (serve quando la 
property deve essere visibile nell'object inspector in caso di un 
oggetto nella palette).
Per rendere le proprieta' visibili nell'object inspector inserire le 
dichiarazioni property nella sezione Published dell'oggetto.
Ciao,
David

Allora... GetStrLen l'hai dichiarata bene mentere SetStrLen deve essere 
dichiarata come procedura e non come funzione ma tutte e due devono fare 
riferimento a MaxLen :
Function MioOggetto.GetStrLen: Integer;
Begin
   Result := MaxLen;
End;
Procedure MioOggetto.SetStrLen (Len: Integer);
Begin
   MaxLen := Len;
End;
Poi, la dichiarazione Default 3 puo' essere tranquillamente eliminata. 
Se la inserisci ricordati di assegnare MaxLen := 3 nella Create 
dell'oggetto.
e, per ultimo, perche' hai usato Const MaxLen = 255? Usa una variabile 
intera no? Oppure, almeno, invece di 255 metti 3 che sarebbe il valore 
di default che usi
Ciao,
David

Ancora una cosuccia che dimenticavo....
se vuoi che una costante sia modificabile a runtime devi dichiarare il 
tipo (Es. MaxLen : Integer = 255) e, ovviamente, devi abilitare 
l'opzione "Assegnable type constants" nelle opzioni del progetto, parte 
"Compiler" (comunque per me, anche se e' ottimo, preferisco che le 
costanti siano costanti e basta)
Ariciao,
David

 forse ti definisci incivile? Fai tu.
Ma quale "modera i toni"! Quanto lassismo!
Ci vogliono veramente TRE secondi (anche meno) per trovare informazioni su
Google e mi pare che questa cosa ti sia stata detta più volte in passato.
Se hai qualche "disorientamento" nel leggere i risultati, temo tu abbia
qualche grosso problema, lasciatelo dire. Capire cos'è e come utilizzare
una property è qualcosa di assolutamente banale, possibile che tu abbia
tutte queste difficoltà? Domandare non è sempre lecito, specie nei gruppi
di discussione. Si presuppone un minimo di impegno alla base di certe
domande.


 occupano di prelevare il contenuto di maxlen o di inserirlo
La convenzione non è questa. La convenzione è NomeProperty, quindi
GetNomeProperty e SetNomeProperty. Il SetNomeProperty accetta un Value del
tipo della property. Del getter si può fare quasi sempre a meno.


Non consiglio nulla. Faccio solamente un elenco delle possibili 
soluzioni errate o meno - chi deve creare il programma, poi, utilizzera' 
questo o quello a seconda di come "gli gira".
Vedi, a differenza di te, non mi va di imporre nulla e non mi reputo un 
saputello: cerco solo di dare una mano e basta

Comunque su una cosa hai ragione (che ho omesso apposta) posso usare o 
meno una funzione per prelevare il valore della property ma non vedo 
perche' mi devo escludere questa possibilita'.
le scritture:
Property Lunghezza : Integer Read VarLen Write SetLen
oppure
Property Lunghezza : Integer Read GetLen Write SetLen
dove VarLen e' una variabile mentre GetLen e' una funzione, sono 
equivalenti e usare una funzione per prelevare un valore intero puo' non 
avere senso se si vuole prelevare il contenuto in una variabile ma puo' 
benissimo avere senso se il valore viene da un calcolo.
Come si dice... "L'esempio lo voglio completo, poi' saro' io a tagliarlo!"

Ciao :)
Grazie per la tua disponibilità, dunque tirando le somme:
  Type   MioOggetto = Class (TObject)
                      Private
                        Const MaxLen = 255;    // Lunghezza Massima Stringa
                        Function GetStrLen: Integer;
                        Procedure SetStrLen (Len: Integer);
                      Public
                        Constructor Create;
                        Function MiaProcedura (Source: String): String;
                      Published
                        Property StrLen: Integer Read GetStrLen Write 
SetStrLen; default;
                      End;
  Constructor MioOggetto.Create;
    Begin
      Inherited Create;
      StrLen := 3;
    End;
  Function MioOggetto.GetStrLen: Integer;
    Begin
      Result := StrLen;
    End;
  Procedure MioOggetto.SetStrLen (Len: Integer);
    Begin
      StrLen := Len;
    End;
Cosi è corretto?
Ho usato la costante MaxLen, perchè il suo valore deve essere tale e non 
deve variare all'interno dell'oggetto.
In altre parole, StrLen non deve superare il valore di MaxLen, e il 
controllo lo effettuo sulla procedura che deve effettuare l'elaborazione 
vera e propria.
C'è solo un problema, alla riga:
   Property StrLen: Integer Read GetStrLen Write SetStrLen; default;
Mi viene restituito l'errore:
   [Pascal Error] MioOggetto.pas(17): E2132 Default property must be an 
array property
In che modo posso ovviare al problema?
Grazie ancora per la tua disponibilità.
Cooper. 

 perche' mi devo escludere questa possibilita'.
Puoi escluderla tranquillamente perché, pur essendo una possibilità, 
puoi sempre aggiungerla in ogni momento, quindi tanto vale non definirla 
da subito, se non occorre. :-)
Ciao,
   Marco.
-- 
MARCO BREVEGLIERI
  (
http://www.marco.breveglieri.name
)

 In che modo posso ovviare al problema?
Secondo me, leggendo la Guida in linea. Hai fatto uso di una direttiva, 
"default", senza conoscere il suo reale significato o ambito di 
utilizzo, oppure fraintendendoli.
Posizionati sulla parola chiave e premi F1 per ottenere le spiegazioni 
che cerchi.


 saputello: cerco solo di dare una mano e basta
Stai attento a dare del "saputello" a chi ne sa sicuramente più di te.
Io non cerco di sfoggiare conoscenze, non me ne può fregare di meno, né
questo ng avrebbe un'importanza così rilevante nella mia vita da meritarsi
una tale attenzione. Sono più di dieci anni che io dò una mano, qui
dentro, quindi, ribadisco, occhio ad usare le parole corrette.


Cooper ha scritto:

Allora andiamo per gradi...
1) default messo cosi' non ha senso
2) Se la proprieta' si chiama StrLen non puoi assegnare (o prelevare il 
valore) nelle funzioni legate GetStrLen e SetStrLen
per semplificare la scrivei cosi':
Type   MioOggetto = Class (TObject)
                     Private
                       Const MaxLen = 255;    // Lunghezza Massima Stringa
		      Var InternalStrLen : Integer;
                       Procedure SetStrLen (Len: Integer);
                     Public
                       Constructor Create;
                       Function MiaProcedura (Source: String): String;
                     Published
                       Property StrLen: Integer Read InternalStrLen Write
SetStrLen; default 3;
                     End;
   Constructor MioOggetto.Create;
     Begin
       Inherited Create;
       StrLen := 3;
     End;
   Procedure MioOggetto.SetStrLen (Len: Integer);
     Begin
       If (InternalStrLen <> Len) And (Len <= MaxLen) Then 
InternalStrLen := Len;
     End;
Come vedi ho eliminato la funzione GetStrLen, ho istanziato una 
variabile interna ed ho inserito il default; se poi vuoi usare la 
funzione GetStrLen la devi implementare facendo riferimento alla 
variabile interna:
.....
Property StrLen : Integer Read GetStrLen Write SetStrLen default 3;
.....
   Function MioOggetto.GetStrLen: Integer;
     Begin
       Result := InternalStrLen;
     End;
Il tuo errore e' credere che una property sia alla stessa stregua di una 
variabile ma non e' cosi' (anche se sembra)
Per tornare all'errore la dicitura DEFAULT senza nulla in una property 
dice al compilatore che quella proprieta' (solo su proprieta' array) e' 
quella di default e si puo' omettere il nome in una chiamata.
Mi spiego:
Mettiamo che hai un oggetto chiamato MioOggetto di tipo TStrings, puoi 
accedere all'elemento 2 o chiamando la proprieta' direttamente 
MioOggetto.Strings[2] oppure omettendo il nome della proprieta' di 
default che in questo caso e' Strings: la chiamata si scrivera' 
MioOggetto[2] - le chiamate MioOggetto.Strings[2] e MioOggetto[2] sono 
identiche -
Ciao,
David

 benissimo avere senso se il valore viene da un calcolo.
Le property quasi sempre mappano un field, ovvero parte dello stato di una
classe, quindi quasi sempre ha senso avere un accesso diretto ad un valore.
Ribadisco: io non ho detto che non devi usare i getter.


 dentro, quindi, ribadisco, occhio ad usare le parole corrette.
Certo e la mano e' Vai su Google! Complimenti

                        Procedure SetStrLen (Len: Integer);
Al posto di Len ci dovrebbe essere un Value.


 Certo e la mano e' Vai su Google! Complimenti
Stai alimentando una polemica sterilissima perché per cose banalissime
(anzi "molto banalissime") è ovvio e naturale che si abbia questo tipo di
risposte. Gente che non si sforza neanche di cercare una soluzione a
problemi così banali non merita altro aiuto che "Google Is Your Friend".
Se poi tu conoscessi la storia di questo ng, sapresti che quasi mai ho
risposto a questo modo.


 problemi così banali non merita altro aiuto che "Google Is Your Friend".
Sbagliato ed in questo thread in particolare.
Cooper ha scritto per avere delucidazioni DOPO che era gia' andato su 
google ed aveva cercato (che poi la ricerca e' stata fatta male e' una 
cosa opinabilissima - nessuno nasce imparato) ma quello che mi ha 
scocciato e' stata la risposta:
 >vai su Google e digita "Delphi property"
 >Cazzo, ma ci vuole tanto??
ti pare una risposta questa? Specie da uno che non era quasi mai stato 
sul gruppo.
Vedi i gruppi di discussione tecnici sono nati per dare una mano anche 
ai "novellini" ed e' grazie a risposte come queste che un gruppo e' 
popolato da fake o flame vari e chi vuole un aiuto semplicemente se ne va.

 popolato da fake o flame vari e chi vuole un aiuto semplicemente se ne va.
I gruppi di discussione sono COLMI e STRACOLMI di "RTFM" e "GIYF".
Probabilmente non li conosci sufficientemente bene. I gruppi sono nati per
discutere, che poi si aiuti qualcuno è una semplice conseguenza. I gruppi
non sono help desk. Prima di porre delle domande, bisogna assicurarsi di
aver cercato e aver cercato bene. Queste sono regole dei ng vecchie come
il cucco. E adesso porrei uno stop a questa polemica.
