Newsgroup: it.comp.lang.visual-basic
Titolo: Aggiungere metodo Clone ad una classe

Salve a tutti,
ho una mia classe che in fase di inizializzazione, va a caricarsi dei dati
da un Database.
Adesso mi serve clonare tale classe 10/15 volte, ma volevo evitare 10
caricamenti ogni volta. E ovviamente se uso il Set è solo un puntatore alla
medesima classe, mentre a me serve che vivano di vita propria.
Dim objClasse as MiaClasse
Dim ArrayClasse(10) as MiaClasse
  Set objClasse = New MiaClasse
  objClasse.Init (parametri)
  For i=0 to 10
    ArrayClasse(i)=objClasse		'senza il Set da errore ovviamente
  Next i
E' possibile fare una cosa del genere?
Grazie a tutti

On 23 Lug, 15:43, "Andrea [Work]"

Visto che citi il "set" direi che stiamo parlando di VB6; in questo
caso no, non si può fare...
o meglio puoi, ma devi implementare tu un metodo che, banalmente, copi
tutti i membri uno ad uno e restituisca la nuova istanza.
Function Clone() as MiaClasse
   Dim myClone As MiaClasse
   Set myClone = New MiaClasse
   With myClone
      .Membro1 = me.Membro1
      .Membro2 = me.Membro2
     '[...]
   End With
   Set Clone=myClone
End Function
Ci sarebbe un sistema meno "ignorante" ma richiederebbe di ridisegnare
la classe su misura per essere clonata: in pratica, internamente, la
classe dovrebbe memorizzare tutte le property non in singole variabili
private come si fa di solito, ma in un unico UDT speculare alla
classe; a questo punto al tuo metodo Clone sarebbe sufficente copiare
quell'unico attributo:
'MiaClasse
Public Type MiaClasseUDT
   Membro1 As String
   Membro2 As Integer
   '[...]
End Type
Private m_PropertyStorage As MiaClasseUDT
Friend Property Get PropertyStorage() As MiaClasseUDT
    PropertyStorage = m_PropertyStorage
End Property
Friend Property Let PropertyStorage(ByVal NewValue As MiaClasseUDT)
    m_PropertyStorage = NewValue
End Property
Public Property Get Membro1()
    Membro1 = m_PropertyStorage.Membro1
End Property
Public Property Let Membro1(ByVal NewValue As String)
    m_PropertyStorage.Membro1 = NewValue
End Property
Public Property Get Membro2()
    Membro1 = m_PropertyStorage.Membro2
End Property
Public Property Let Membro2(ByVal NewValue As String)
    m_PropertyStorage.Membro2 = NewValue
End Property
'[...] altre property
Function Clone() As MiaClasse
   Dim myClone As MiaClasse
   Set myClone = New MiaClasse
   myClone.PropertyStorage = Me.PropertyStorage
   Set Clone = myClone
End Function
Chiaramente con tipi semplici funziona bene, con property a loro volta
complesse (tipi o peggio ancora riferimenti ad altri oggetti) la
faccenda si complica perchè dovresti navigare tutta la catena... vedi
tu se ne vale la pena

On 23 Lug, 15:43, "Andrea [Work]"
<andrea.isworkDELET...@gmail.invalid> wrote:

Un'altra alternativa, non è un metodo di clonaggio ma è più facile
rispetto a quella che ho postato un attimo fa: fai un'altra classe che
supporti solo il metodo Init(), identico alla tua classe originaria,
fai in modo pero' che restituisca una collection o un array
(collection è piu' semplice); a questo punto semplicemente fai un
unico accesso al DB nel nuovo metodo Init, ma in un ulteriore ciclo
popola gli n oggetti che ti servono.
'MiaClasseMamma
Public Function Init(ByVal parametri As XXX, ByVal count As Integer)
As Collection
Dim lista As Collection
Dim obj As MiaClasse
'[..] quello che serve per accedere al DB
Set lista = New Collection
Do While Not Recordset.EOF
    For i = 1 To count
        Set obj = New MiaClasse
        '[...] lettura dal recordset
        lista.Add obj
    Next
    Recordset.MoveNext
Loop
'[...] chiusura e pulizia
Set Init = lista
End Function
la chiamata iniziale diventa
Dim objClasseMamma as MiaClasseMamma
Dim listaMiaClasse as Collection
Set objClasseMamma = New MiaClasseMamma
Set listaMiaClasse= objClasseMamma.Init (parametri, 10)

Luca D ha scritto:
 >...
nn mi intendo di vb6...ma non è quello che si ottiente usando il 
costruttore new?
saluti MVB

 popola gli n oggetti che ti servono.
Ti ringrazio.
Ora valuto un attimino, potrei anche caricare esternamente i dati nella
classe, cioè non sfruttare la classe interna ma popolare le variabili
esterna
DO until Rs.eof
  for i = 0 to 10  
    arrayClasse(i)= New classe
    arrayclasse(i).proprietà1=Rs.fields("campo1").value
    arrayclasse(i).proprietà2=Rs.fields("campo2").value
    arrayclasse(i).proprietà3=Rs.fields("campo3").value
  next i
  rs.movenext
loop
Anche perchè questa è la prima bozza del sw, e potrebbe cambiare in corso
d'opera :\.

 medesima classe, mentre a me serve che vivano di vita propria.
...aiuto....chiariscimi!
io ho una classe....la istanzio con new....
prende e si "fà posto"...in memoria ram...gestita non gestita quello che 
vuoi !
in memoria ho un puntatore (anche questo chaimalo come vuoi!)
alla sua "zona"(anche questo chiamalo come vuoi...spazio di 
indirizzamento...Anselmo...Giuda da Velletri...come vuoi!)
ORA
se vuoi "clonare"....
puoi fare in 2 modi.....Clonare il puntatore.....ne hai 2 che puntano alla 
STESSA area
Clonare lo spazio...hai un area ad un diverso puntatore con i medesimi dati!
Io presuppongo che tu voglia fare il secondo:
metodo ad alto livello
....mi leggo i dati UNA VOLTA...li stocco temporaneamente da qualche 
parte....creo con new tante classi quanto ne voglio e li assegno i valori 
che ho in memoria!
Il fatto che le classi invece che chiamarsi pippo1 pippo 2 pippo3 siano 
nella collezione FamigliaDePippis...mi aiuta solo concettualmente a tenere 
ordine nei miei incasinati neuroni!
in NET hai un aiuto un po più amichevole....hai l'interfaccia IClonable (se 
non ricordo male)...ma se vuoi un deep copy della tua classe custom devi 
comunque spippolare lo stesso di codice!
metodo a basso livello....
individui l'area di memoria....ne allochi un altra ...e ci ricopi la 
vecchia...il nuovo puntatore è la nuova classe
Se pò fà in vb6?...certo che no!....o meglio.... devi spippolare di 
API....io non c'ho provato con una classe(mi son fermato ad una 
variabile...e solo per pura voglia di provare!)....
però questo esempio lo fà per copiare un array in un altro
http://www.vb-helper.com/howto_copy_memory.html
in C++ sarebbe un "pelino più facile"....
in VB.net non so....
però visto che si parla di classi e di spazio di memoria managed....ci sarà 
qualche namespace nell'immenso mare del framework che ricopierà zone di 
memoria allocata!...o no?...boh!
;-) 

 che ho in memoria!
Infatti è quello che farò :-)
Farò la mia select esterna alla classe, inizializzo la classe senza farle
caricare nulla, e setto le property a mano.
Anche perchè saranno 8/10 property, solo che la select da cui pescano è
abbastanza complessa e non istantanea.
Grazie

 indirizzamento...Anselmo...Giuda da Velletri...
appena ci vediamo (zio gibi, datti una mossa per settembre, che sono gia' 
prenotato per lezioni di storia al grillino...), mi spieghi per filo e per 
segno chi e' giuda da velletri. sembra simpatico. tradisce per trenta 
caciotte? :)