Newsgroup: it.comp.lang.visual-basic
Titolo: .NET, ma la classe string è un tipo riferimento oppure no???

il mio libro dice di si,
in teoria col codice seguente modificando il valore della variabile s2 si
dovrebbe
modificare anche quello di s1....
... ma in pratica no, perchč?
dim s1 as string ="francesco"
dim s2 as string =s1
s2 = "carlo"
console.writeline(s1)
carlo

console.writeline(s1)
'stampa francesco
In pratica Carlo, sono tipi di riferimento, ma hanno adottato un
comportamento particolare,
(quello della creazione di un nuovo oggetto, in luogo di modifica) perché da
un punto di vista
"umano" è più logico che le stringhe siano utilizzate come se fossero
semplici valori.
Difatto le stringhe sono anche particolari per gli overload degli operatori.
Basta non fare confusione... :o))
Ciao,
Antonio Cangiano
--
"C# is the future."
Where Do You Want To Go Today?

Un aspetto fondamentale che riguarda le stringhe è che, per definizione,
sono immutabili
Ovvero se scrivi:
Dim s1 as string = "Ciao"
s1 = "Ciao2"
Nella seconda assegnazione il CLR crea un nuovo oggetto stringa contenente
"Ciao2" e lo assegna alla variabile s1 (la quale prima puntava all'oggetto
"Ciao").
L'oggetto "Ciao" verrà eliminato non appena il Garbage Collector richiamerà
memoria.
Nel tuo caso, l'assegnazione di "carlo" a s2 fa si che un nuovo oggetto
"Carlo" venga assegnato alla variabile che prima,effettivamente, puntava a
s1.
Come ulteriore conferma:
      Dim s1 As String = "francesco"
      Dim s2 As String = s1
      Debug.WriteLine(s1 Is s2)   '// true (puntano allo stesso oggetto)
      s2 = "carlo"
      Debug.WriteLine(s1 Is s2)   '// False (s2 ora punta a un nuovo
oggetto)
HTH
Corrado

 sono immutabili
Domanda: ma funziona così anche per gli altri tipi di oggetto?
Cioè, sempre facendo
a = new a()
b = new a()
a = b
il primo new a(), si perde?
Andava prima settato a nothing (o null in C#)?
Andava fatta una .Destroy()?
Ciao

 ha scritto nel messaggio
news:W3D%8.133137$vm5.4...@news2.tin.it...


       Debug.WriteLine(oT2.Name)    '// Uno
Ok, grazie, infatti era quello che mi aspettavo.
Allora rinnovo la domanda: qual'č il metodo corretto?
a = new a()
b = new a()
a = b ' e il mio <a> originale dove č andato a finire?
      ' č perso nella memoria?
e quando c'č un membro con un prototipo come questo:
 sub mysub(param as myclass)
vedo spesso usare
 classe1.mysub(new myclass())
ma anche qui... quest'istanza dove si perde?
non sarebbe piů corretto (ma decisamente piů scomodo)
 c = new myclass()
 classe1.mysub(c)
 c.Destroy()
?
Ciao

 ma anche qui... quest'istanza dove si perde?
[SNIP]
La risposta e' sempre quella (come la merendina :-)): Garbage Collector
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

 Collector
Ah, quindi ci si può fidare ;)
Dunque è correto non preoccuparsi della distruzione degli oggetti?
E tutto il discorso suglle classi Disposable?
Ciao


ciao,
A.
UGIdotNET - 
http://www.ugidotnet.org

Praticamente si, in realtà se hai qualche oggetto che non può (o meglio non
deve) aspettare che il GC distrugga l'istanza puoi, come ha descritto Andrea
implementare l'interfaccia IDisposable e fare l'overriding della Finalize.
L'overriding della Finalize rallenta l'eliminazione dell'oggetto dalla
memoria (in pratica deve aspettare 2 reclaiming) quindi tutti questi
discorsi sono da applicare per gli oggetti che hanno bisogno, per propria
natura, di rilasciare alcune risorse quando l'oggetto non è più in uso.
Per gli altri casi, lascia fare al Garbage Collector.
Ciao
Corrado

 Per gli altri casi, lascia fare al Garbage Collector.
Grazie a tutti e 3, ora è molto più chiaro.
Solo una cosa: quindi io posso tranquillamente fare la
new miaclasse()
e lasciare fare al collezionista di immondizia anche se miaclasse è
disposeable?
Ciao

Certo, l'Implementazione di IDisposable serve per implementare in modo
"standard" un metodo che gli utilizzatori della tua classe devono invocare
prima di settare l'oggetto a Nothing (e che tu devi ovviamente informare).
Attenzione che il GC non invoca il metodo cClose della IDisposable ma, di
fatto, invoca, la Sub Finalize (che è protected, quindi overridable)
Come indicazione "generica" da applicare quando un oggetto deve rilasciare
risorse prima che venga pulito dal GC
1) Implementa IDisposable
2) Il metodo Close della IDisposable invoca una routine che libera quello
che deve essere rilasciato e poi informa il GC che non deve invocare la
Finalize utilizzando GC.SuppressFinalize
3) Override della Finalize la quale invoca la stessa funzione invocata dal
meodo della IDisposable
Perchè è necessario il punto 3? perchè se ti dimentichi di invocare il
metodo della IDisposable comunque il GC alla fine rilascia comunque le
risorse occupate dall'oggetto (quando non si sa).
Perchè serve GC.SuppressFinalize? Perchè gli oggetti che implementano la
Finalize stanno in vita più tempo degli altri oggetti (a causa di un
fenomeno chiamato resurrection), utilizzando la GC.SuppressFinalize informi
il GC che alla prima 'pulizia' puo liberare l'oggetto in quanto le risorse
sono state rilasciate correttamente dall'utente attraverso la IDisposable.
HTH
Corrado

quanto perfettamente espresso da Corrado si può quindi tradurre nel seguente
pattern:
    Public Sub UsaClasse()
        Dim o As New MiaClasse()
        o.MioMetodo()
        o.Dispose()
        o = Nothing
    End Sub
    Public Class MiaClasse
        Implements IDisposable
        Public Sub MioMetodo()
        End Sub
        Public Sub Dispose() Implements IDisposable.Dispose
            GC.SuppressFinalize(Me)
            'Rilascio delle risorse
        End Sub
        Protected Overrides Sub Finalize()
            Dispose()
            MyBase.Finalize()
        End Sub
    End Class
in questo modo, il corretto rilascio delle risorse avverrà sia se lo
sviluppatore è stato bravo (ossia ha invocato Dispose), sia se non lo è
stato. Perdonatemi le smancerie, ma volevo ringraziare il NG per lo
splendido thread.
