JavascriptProva

mercoledì 31 luglio 2013

Ereditarietà e overloading dei costruttori.

Si dice che i costruttori non vengono ereditati.
Qui ho un'evidenza differente:
Module Module1

    Sub Main()
        Dim miaClasse As New Classe
        Dim secondaClasse As New Classe(2)
        Dim terzaClasse As New Classe(2, "ciao")

        Dim miaDerivata As New Derivata

    End Sub

End Module

Class Classe
    Sub New()
        Console.WriteLine("Costruttore senza parametri")
        Console.ReadKey()
    End Sub

    Sub New(ByVal parametro As Integer)
        Console.WriteLine("Costruttore con un parametro")
        Console.ReadKey()
    End Sub

    Sub New(ByVal parametro As Integer, ByVal parametro2 As String)
        Console.WriteLine("Costruttore con due parametri")
        Console.ReadKey()
    End Sub
End Class

Class Derivata
    Inherits Classe

End Class
Se istanzio la classe derivata senza parametri, questa eredita il costruttore senza parametri della classe base.
Infatti l'output mi mostra il risultato dell'istanziazione della classe base mediante i suoi tre costruttori, e successivamente il risultato dell'istanziazione della classe derivata mediante il costruttore senza parametri della classe base, che quindi è necessariamente ereditato:
Costruttore senza parametri
Costruttore con un parametro
Costruttore con due parametri
Costruttore senza parametri




Proviamo adesso ad aggiungere l'istanziazione della classe derivata mediante i costruttori con parametri:
Module Module1

    Sub Main()
        Dim miaClasse As New Classe
        Dim secondaClasse As New Classe(2)
        Dim terzaClasse As New Classe(2, "ciao")

        Dim miaDerivata As New Derivata
        Dim secondaDerivata As New Derivata(2)
        Dim terzaDerivata As New Derivata(2, "ciao")

    End Sub

End Module

Class Classe
    Sub New()
        Console.WriteLine("Costruttore senza parametri")
        Console.ReadKey()
    End Sub

    Sub New(ByVal parametro As Integer)
        Console.WriteLine("Costruttore con un parametro")
        Console.ReadKey()
    End Sub

    Sub New(ByVal parametro As Integer, ByVal parametro2 As String)
        Console.WriteLine("Costruttore con due parametri")
        Console.ReadKey()
    End Sub
End Class

Class Derivata
    Inherits Classe

End Class
Ecco: ottengo l'errore già in fase di scrittura del codice.
Errore 1 Troppi argomenti per 'Public Sub New()'.
Errore 2 Troppi argomenti per 'Public Sub New()'.


Dunque la conclusione è che il costruttore senza parametri può essere ereditato, mentre i costruttori con parametri no.
Ma, come sospettavo, aggiungiamo i costruttori con parametri nel codice della classe derivata senza specificare il costruttore senza parametri, e ne vedremo delle belle:
Class Derivata
    Inherits Classe

    Sub New(ByVal parametro As Integer)
        Console.WriteLine("Costruttore con un parametro")
        Console.ReadKey()
    End Sub

    Sub New(ByVal parametro As Integer, ByVal parametro2 As String)
        Console.WriteLine("Costruttore con due parametri")
        Console.ReadKey()
    End Sub
E istanziamo:
        Dim miaDerivata As New Derivata
        Dim secondaDerivata As New Derivata(2)
        Dim terzaDerivata As New Derivata(2, "ciao")
Ottengo un errore nell'istanziare la classe derivata col costruttore senza parametri:
Errore 1 Risoluzione dell'overload non riuscita perché nessun 'New' accessibile accetta questo numero di argomenti.

Conclusione:
Se non esistono costruttori con parametri nella classe derivata, il costruttore di default (senza parametri) viene ereditato, mentre se esistono costruttori con parametri nella classe derivata, il costruttore di default va specificato espressamente!

Overloading dei costruttori nell'ambito di una classe.

Avevo già ripassato la cosa qualche tempo fa

Qui c'è praticamente un overloading dei costruttori nell'ambito della stessa classe.

Mi rifaccio un altro esempio.

Module Module1

    Sub Main()
        Dim miaClasse As New Classe
        Dim secondaClasse As New Classe(2)
        Dim terzaClasse As New Classe(2, "ciao")
    End Sub

End Module

Class Classe
    Sub New()
        Console.WriteLine("Costruttore senza parametri")
        Console.ReadKey()
    End Sub

    Sub New(ByVal parametro As Integer)
        Console.WriteLine("Costruttore con un parametro")
        Console.ReadKey()
    End Sub

    Sub New(ByVal parametro As Integer, ByVal parametro2 As String)
        Console.WriteLine("Costruttore con due parametri")
        Console.ReadKey()
    End Sub
End Class

Analogamente a quanto accade, se ricordo bene, nel C++, il costruttore senza parametri si considera automaticamente esistente se è l'unico, ossia se non viene "overloadato", mentre se c'è un altro costruttore con parametri esso deve essere dichiarato esplicitamente.
Ho fatto un po' di prove...
Module Module1

    Sub Main()
        Dim miaClasse As New Classe
        Dim secondaClasse As New Classe(2)
        Dim terzaClasse As New Classe(2, "ciao")
    End Sub

End Module

Class Classe


    Sub New(ByVal parametro As Integer)
        Console.WriteLine("Costruttore con un parametro")
        Console.ReadKey()
    End Sub

    Sub New(ByVal parametro As Integer, ByVal parametro2 As String)
        Console.WriteLine("Costruttore con due parametri")
        Console.ReadKey()
    End Sub
End Class
Ecco: in questo caso ho tolto il costruttore di default, quello senza parametri, e ottengo una segnalazione di errore già in fase di scrittura del codice: "Errore 1 Risoluzione dell'overload non riuscita perché nessun 'New' accessibile accetta questo numero di argomenti."

Adesso elimino gli altri costruttori (e ovviamente anche le istanziazioni della classe che ne fanno uso).
Module Module1

    Sub Main()
        Dim miaClasse As New Classe
       
    End Sub

End Module

Class Classe

End Class
Si tratta della classe più fessa del mondo, ma quello che mi interessa è il concetto: adesso non ottengo più alcuna segnalazione di errore, perchè in assenza di overloading dei costruttori il costruttore di default, quello senza parametri, viene dato per sottinteso e quindi l'istanziazione della classe con quel costruttore mi viene riconosciute come lecita.

Overloading di un metodo.

Cerchiamo di giocare con l'overload e l'override...
Si tratta di argomenti un tantino confusivi...

Iniziamo con una classe incredibilmente semplice...
Module Module1

    Sub Main()
        Dim miaClasse As New Classe
        miaClasse.metodo()


    End Sub

End Module

Class Classe
    Sub metodo()
        Console.WriteLine("Io sono la classe base")
        Console.ReadKey()

    End Sub
End Class
Output:
Io sono la classe base



Adesso creiamo una classe derivata:
    Sub Main()
        Dim miaClasse As New Classe
        miaClasse.metodo()


    End Sub

End Module

Class Classe
    Sub metodo()
        Console.WriteLine("Io sono la classe base")
        Console.ReadKey()

    End Sub
End Class

Class Derivata
    Inherits Classe

    Sub metodo()
        Console.WriteLine("Io sono la classe derivata")

    End Sub
End Class
Nel metodo della classe derivata ottengo una segnalazione di errore:
"sub 'metodo' nasconde un membro che supporta l'overload dichiarato nella class base 'Classe'. Per eseguire l'overload del metodo di base, quest'ultimo deve essere essere dichiarato 'Overloads' "
Che significa tutto questo?
Significa probabilmente che posso eseguire l'overload del metodo 'metodo', ossia avere due metodi con lo stesso nome ma con diversi parametri, il che significa la possibilità di usare uno stesso metodo con diversi parametri.
Per fare questo, devo dichiarare questo metodo della classe derivata "overloads".

Proviamo...
Module Module1

    Sub Main()
        Dim miaClasse As New Classe
        miaClasse.metodo()
        Dim miaDerivata As New Derivata
        miaDerivata.metodo()

    End Sub

End Module

Class Classe
    Sub metodo()
        Console.WriteLine("Io sono la classe base")
        Console.ReadKey()

    End Sub
End Class

Class Derivata
    Inherits Classe

    Overloads Sub metodo()
        Console.WriteLine("Io sono la classe derivata")
        Console.ReadKey()

    End Sub
End Class
Ho semplicemente dichiarato Overloads il metodo della classe derivata, senza modificarne i parametri.
Non mi pare che la cosa abbia poi molto senso.
L'output è il seguente:
Io sono la classe base
Io sono la classe derivata




In pratica, quando istanzio la classe base, viene eseguito il metodo della classe base, mentre quanto istanzio la classe derivata viene eseguito il metodo della classe derivata. E' come se usassi l'override, in cui il metodo della classe derivata sostituisce il metodo della classe base...

Proviamo a modificare i parametri...
Module Module1

    Sub Main()
        Dim miaClasse As New Classe
        miaClasse.metodo()
        Dim miaDerivata As New Derivata
        miaDerivata.metodo()

    End Sub

End Module

Class Classe
    Sub metodo()
        Console.WriteLine("Io sono la classe base")
        Console.ReadKey()

    End Sub
End Class

Class Derivata
    Inherits Classe

    Overloads Sub metodo(ByVal parametro As String)
        Console.WriteLine("Io sono la classe derivata")
        Console.ReadKey()

    End Sub
End Class
Ecco, ora ho fatto un vero overload, ossia nella classe derivata avrò due metodi, uno senza parametri e uno con un parametro di tipo String.
E se istanzio la classe derivata eseguendone il metodo senza parametri, mi verrà eseguito il metodo della classe base:
Io sono la classe base
Io sono la classe base


Invece adesso provo ad eseguire, dopo aver istanziato la classe derivata, il metodo con parametro di tipo String e vediamo:
    Sub Main()
        Dim miaClasse As New Classe
        miaClasse.metodo()
        Dim miaDerivata As New Derivata
        miaDerivata.metodo("Ciao ciccio")

    End Sub
Ecco l'output:
Io sono la classe base
Io sono la classe derivata


Perfetto!
Con l'Overload posso avere un metodo da usare in modo versatile, con numero e tipo diverso di parametri.

Ovviamente posso overloadare un metodo anche nell'ambito della stessa classe:
Module Module1

    Sub Main()
        Dim miaClasse As New Classe
        miaClasse.metodo()
        miaClasse.metodo(123)
        miaClasse.metodo(345, "Fesso")

    End Sub

End Module

Class Classe
    Sub metodo()
        Console.WriteLine("Io sono il metodo senza parametri")
        Console.ReadKey()

    End Sub

    Sub metodo(ByVal parametro As Integer)
        Console.WriteLine("Io sono il metodo con parametro")
        Console.ReadKey()

    End Sub

    Sub metodo(ByVal parametro As Integer, ByVal parametro2 As String)
        Console.WriteLine("Io sono il metodo con due parametri")
        Console.ReadKey()
    End Sub
End Class
Output:
Io sono il metodo senza parametri
Io sono il metodo con parametro
Io sono il metodo con due parametri


Ecco l'overloading!

lunedì 29 luglio 2013

Ereditarietà, visibilità di membri Private, Protected e Public dalle classi derivate.

Ereditiamo...

Questa è la classe base:
Class miaClasse
    Private nome As Int32 = 444
    Private Property proprieta() As Int32
        Get
            Return nome
        End Get

        Set(ByVal value As Int32)
            nome = value
        End Set
    End Property

    Sub propertySetting(ByVal valore As Int32)
        proprieta = valore
    End Sub

    Sub metodo()
        MsgBox(proprieta)
    End Sub

End Class


E creo una classe derivata:
Class miaClasseDerivata
    Inherits miaClasse
    Sub altroMetodo()
        MsgBox("Io sono una classe derivata e questa è la mia proprietà " & proprieta)
    End Sub
End Class
Bene: ottengo un errore che mi viene notificato dall'IDE già in fase di scrittura del codice: Errore 1 'WindowsApplication1.miaClasse.Private Property proprieta As Integer' non è accessibile in questo contesto perché è 'Private'. C:\Users\Antonello\documents\visual studio 2010\Projects\WindowsApplication1\WindowsApplication1\Form1.vb 37 77 WindowsApplication1

Questo perchè il metodo della classe derivata non può accedere a una proprietà Private della classe madre.

Però, pur nella classe derivata, il metodo ereditato dalla classe madre può accedere a un membro Private.

Istanziando la classe derivata e chiamando un metodo ereditato dalla classe madre, questo metodo può mostrare tranquillamente in una MessageBox il valore della proprietà Private.
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim questaClasse As New miaClasseDerivata
        questaClasse.metodo()
        questaClasse.metodo()

        
    End Sub


Tutto questo va tenuto bene in mente.
Adesso faccio in modo che il metodo della classe derivata possa avere accesso alla proprietà, dichiarandola Protected:
Class miaClasse
    Private nome As Int32 = 444
    Protected Property proprieta() As Int32
        Get
            Return nome
        End Get

        Set(ByVal value As Int32)
            nome = value
        End Set
    End Property

    Sub propertySetting(ByVal valore As Int32)
        proprieta = valore
    End Sub

    Sub metodo()
        MsgBox(proprieta)
    End Sub

    
End Class

Class miaClasseDerivata
    Inherits miaClasse
    Sub altroMetodo()
        MsgBox(proprieta)
    End Sub
End Class
Non ottengo errori in fase di scrittura del codice...
...e istanziando in questo modo:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim questaClasse As New miaClasseDerivata
        questaClasse.altroMetodo()
    End Sub
...ottengo una MessageBox con il valore della proprietà ereditata dalla classe madre!
Con la proprietà Public il problema, ovviamente, non si pone:
Class miaClasse
    Private nome As Int32 = 444
    Public Property proprieta() As Int32
        Get
            Return nome
        End Get

        Set(ByVal value As Int32)
            nome = value
        End Set
    End Property

    Sub propertySetting(ByVal valore As Int32)
        proprieta = valore
    End Sub

    Sub metodo()
        MsgBox(proprieta)
    End Sub

    
End Class

Class miaClasseDerivata
    Inherits miaClasse
    Sub altroMetodo()
        MsgBox(proprieta)
    End Sub
End Class

Incapsulamento

Se ricordo bene, l'incapsulamento consiste nel predisporre dei precisi canali d'accesso a una classe, mantenendo privato tutto ciò che si può, e manipolandolo attraverso questi specifici canali.

Provo un "incapsulamento" sulla piccola classe che ho creato a titolo di esercizio...

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim questaClasse As New miaClasse
        questaClasse.propertySetting(789)
        questaClasse.metodo()
    End Sub

End Class
Class miaClasse
    Private nome As Int32 = 444
    Private Property proprieta() As Int32
        Get
            Return nome
        End Get

        Set(ByVal value As Int32)
            nome = value
        End Set
    End Property

    Sub propertySetting(ByVal valore As Int32)
        proprieta = valore
    End Sub

    Sub metodo()
        MsgBox(proprieta)
    End Sub

End Class
Ecco: il valore della proprietà (che di default è 444) viene stabilito da un metodo pubblico, mentre la proprietà è stata resa privata. Si dovrebbero evitare così manipolazioni inopportune del valore della proprietà da esterno.

Property get e set, impostazione di un valore di default per una proprietà di una classe.

L'uso di Get e Set per le proprietà...
La proprietà si può definire anche con una semplice dichiarazione di una variabile.
Però l'uso della routine Property permette alcuni giochetti, come l'impostare un valore di default per una proprietà.

Qui abbiamo un valore di default pari a 444, impostando la variabile nome a 444.
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim questaClasse As New miaClasse

        questaClasse.metodo()
    End Sub

End Class
Class miaClasse
    Dim nome As Int32 = 444
    Public Property proprieta() As Int32
        Get
            Return nome
        End Get

        Set(ByVal value As Int32)
            nome = value
        End Set
    End Property

    Sub metodo()
        MsgBox(proprieta)
    End Sub

End Class
Il risultato visualizzato nella MessageBox è 444.
Adesso impostiamo la proprietà da esterno a 12345:
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim questaClasse As New miaClasse
        questaClasse.proprieta = 12345
        questaClasse.metodo()
    End Sub

End Class
Class miaClasse
    Dim nome As Int32 = 444
    Public Property proprieta() As Int32
        Get
            Return nome
        End Get

        Set(ByVal value As Int32)
            nome = value
        End Set
    End Property

    Sub metodo()
        MsgBox(proprieta)
    End Sub

End Class
Il risultato visualizzato nella MessageBox è 12345


Quindi, se non viene specificato nessun valore della proprietà, essa è, di default, pari a 444, mentre se viene specificato un valore la proprietà assume il valore specificato.

Ripasso delle classi in VB.NET

Rinfreschiamoci le classi...

Ecco una semplice classe, con una proprietà e un metodo, istanziata al caricamento del form.
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim questaClasse As New miaClasse
        questaClasse.metodo()

    End Sub

   
End Class
Class miaClasse
    Dim proprieta As Int32 = 246
    Sub metodo()
        MsgBox(proprieta)
    End Sub

End Class
...laddove la proprietà è marcata in rosso, il metodo in blu.

Adesso rinfreschiamoci il costruttore.

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim questaClasse As New miaClasse


    End Sub

   
End Class
Class miaClasse
    Dim proprieta As Int32 = 246

    Sub New()
        MsgBox("questo è il costruttore")
    End Sub

    Sub metodo()
        MsgBox(proprieta)
    End Sub

End Class
...laddove la proprietà è in rosso, il metodo in blu e il costruttore in verde.
Qui non appena la classe è stata istanziata scatta immediatamente il "metodo" New, ossia quello che viene chiamato all'istanziazione della classe, praticamente la funzione svolta dal costruttore nella sintassi del C++.

domenica 28 luglio 2013

Introduzione ai tipi generici in VB.NET

Uso dei generici:

Ecco un codice:
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        disponi(Of ListBox)()

    End Sub

    Sub disponi(Of T As New)()
        Dim testo As New T

        If TypeOf (testo) Is Control Then
            MsgBox("Control")
        Else
            MsgBox("No control")
        End If

    End Sub
End Class


Questo codice l'ho creato per studiare i generici in funzione del rendere autonomo il codice che dispone controlli in righe e tabelle su un form, in modo da poterlo usare con diversi tipi di controlli.

Disposizione di controlli (TextBoxes) a runtime in righe e colonne

Adesso vorrei disporre diverse textboxes una sopra l'altra.
Non mi ricordo la tecnica...

Ecco: il Top viene ottenuto dal risultato intero della divisione del numero ordinale della casella per il numero di caselle in una riga, mentre il Left viene ottenuto dal risultato del modulo del numero ordinale della casella per il numero di caselle in una riga.

Mi pare che sia così...

Non precipitiamo... Facciamo ora una semplice colonna di caselle (TextBox)

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For n = 0 To 9
            Dim txt As New TextBox
            txt.Top = txt.Height * (n / 1)
            Controls.Add(txt)
        Next
        
    End Sub
Ecco: ho voluto aggiungere a runtime dieci TextBoxes impilate, con righe della lunghezza di 1.



Ora provo con righe di tre elementi.

E mi viene una porcheria! Grazie! Ho scordato di rendere intero il risultato della divisione! Finchè la divisione era per uno, il risultato era necessariamente intero, essendo rappresentato dal dividendo pari pari... ma adesso, dividendo per un numero diverso, viene fuori la cavolata!

Ricordo vagamente uno slash inverso come operatore di divisione intera... ricordo bene?

Sembrerebbe proprio di sì!

E infatti:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For n = 0 To 9
            Dim txt As New TextBox
            txt.Top = txt.Height * (n \ 3)
            txt.Left = txt.Width * (n Mod 3)
            Controls.Add(txt)
        Next
        
    End Sub
...adesso riesce tutto alla perfezione:

Creazione e aggiunta di un controllo a runtime:

Creazione e aggiunta di un controllo a runtime:
Ecco il codice:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim testo As New TextBox
        testo.Text = "Ciao bello"
        Me.Controls.Add(testo)
    End Sub

Ed ecco il form:


La fonte

Esercizietto stupido ed elementare: una List di TextBoxes.

Bene.
Per il momento usiamo le List.

Ora faccio un esercizio, aggiungendo a una List degli oggetti.

Public Class Form1
    Dim elenco As New List(Of TextBox)
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        elenco.Add(TextBox1)
        elenco.Add(TextBox2)
        elenco.Add(TextBox3)
        For Each elemento In elenco
            MsgBox(elemento.Name)
        Next
    End Sub
End Class
Ecco creata una lista di TextBoxes.

venerdì 26 luglio 2013

ArrayList e casting?

Bene.
Praticamente ogni elemento di un'ArrayList si "casta" da solo...
Sottoponendo a un'operazione ogni membro dell'arraylist esso risponde all'operazione adeguata.

Forse ci sono problemi per quanto riguarda gli oggetti...

mercoledì 17 luglio 2013

L'ArrayList, a differenza dell'Array, non è tipizzato!

Ecco, però l'ArrayList non è "tipizzato": è un minestrone in cui dentro ci può andare di tutto.
    Sub Main()
        Dim List As New ArrayList
        Dim carciofi As Integer = 12345
        Dim finocchi As Boolean = True
        List.Add("patate")
        List.Add(carciofi)
        List.Add(finocchi)
        For n = 0 To 2
            Console.WriteLine(List(n))
        Next
        Console.ReadKey()
    End Sub
patate
12345
True



Questo pone problemi di casting... che vedrò fra poco di capire.

Studio su come viene gestito il ridimensionamento dell'ArrayList a livello di Heap, in confronto con l'Array.

Veniamo ora all'usi di ArrayList.

Ecco il codice, simile a quello usato per gli array, che dimostra come un ArrayList, pur ridimensionandosi, resta sempre nella stessa locazione dello Heap, e dunque l'identificatore ha nello stack sempre il medesimo valore, ossia punta sempre nella medesima locazione, nonostante le modificazioni di lunghezza dell'arraylist.
    Sub Main()
        Dim List As New ArrayList
        Dim SecondaList As ArrayList
        SecondaList = List
        List.Add("uno")
        List.Add("due")
        List.Add("tre")
        Console.WriteLine(List(2))
        Console.WriteLine("La lunghezza della List è " & List.Count)
        Console.WriteLine("La proposizione secondo cui SecondaList si identifica con List è " & (SecondaList Is List))
        Console.ReadKey()
        List.Add("quattro")
        Console.WriteLine()
        Console.WriteLine(List(3))
        Console.WriteLine("La lunghezza della List è " & List.Count)
        Console.WriteLine("La proposizione secondo cui SecondaList si identifica con List è " & (SecondaList Is List))
        Console.ReadKey()
    End Sub
Ecco l'output:
tre
La lunghezza della List è 3
La proposizione secondo cui SecondaList si identifica con List è True

quattro
La lunghezza della List è 4
La proposizione secondo cui SecondaList si identifica con List è True



Molto chiaro!
Ecco dunque una differenza fondamentale fra array e ArrayList.

Studio su come vengono gestiti gli arrays ridimensionati in termini di creazione nello heap.

Che differenza c'è fra un array e un arraylist?
Bene, si possono usare le arraylist quando si devono ridimensionare arrays.
Infatti mi pare di ricordare che un array, quando viene ridimensionato, in realtà viene creato come nuovo array. Mi rifaccio il test che avevo ideato prima...

    Sub Main()
        Dim MyArray As String()
        Dim SecondoArray As String()
        MyArray = {"uno", "due", "tre"}
        SecondoArray = MyArray
        Console.WriteLine(MyArray(0))
        Console.WriteLine(SecondoArray Is MyArray)
        Console.ReadKey()
        ReDim Preserve MyArray(3)
        MyArray(3) = "quattro"
        Console.WriteLine(MyArray(3))
        Console.WriteLine(SecondoArray Is MyArray)
        Console.ReadKey()

    End Sub
Ecco l'output:
uno
True
quattro
False


Questo significa che dopo il ReDim Preserve viene scritto nell'Heap un nuovo array con una locazione diversa.

Ci aggiungo dell'altro codice per vedere invece se la variabile SecondoArray resta sempre quella di prima.
    Sub Main()
        Dim MyArray As String()
        Dim SecondoArray As String()
        MyArray = {"uno", "due", "tre"}
        SecondoArray = MyArray
        Console.WriteLine(MyArray(0))
        Console.WriteLine("la proposizione secondo cui SecondoArray si identifica con MyArray è " & (SecondoArray Is MyArray))
        Console.WriteLine("Lunghezza di MyArray " & MyArray.Length)
        Console.WriteLine("Lunghezza di SecondoArray " & SecondoArray.Length)
        Console.ReadKey()
        ReDim Preserve MyArray(3)
        MyArray(3) = "quattro"
        Console.WriteLine()
        Console.WriteLine(MyArray(3))
        Console.WriteLine("la proposizione secondo cui SecondoArray si identifica con MyArray è " & (SecondoArray Is MyArray))
        Console.WriteLine("Lunghezza di MyArray " & MyArray.Length)
        Console.WriteLine("Lunghezza di SecondoArray " & SecondoArray.Length)
        Console.ReadKey()

    End Sub
Ecco, ci ho aggiunto del codice più "esplicativo", che "parla un po' più chiaro":
uno
la proposizione secondo cui SecondoArray si identifica con MyArray è True
Lunghezza di MyArray 3
Lunghezza di SecondoArray 3

quattro
la proposizione secondo cui SecondoArray si identifica con MyArray è False
Lunghezza di MyArray 4
Lunghezza di SecondoArray 3


Dunque è chiaro che con il ReDim Preserve in realtà non si ridimensiona un bel niente, ma viene creato un nuovo array nello Heap, cui "punta" la variabile presente nello stack.

lunedì 15 luglio 2013

Programmazione di Tomb Raider...

Apro Level Editor.

Project -> Load -> maps/tut1/tut1.PRJ

Provo a fare output wad: mi si salva un file con estensione TOM in graphics/wad

Dimenticato di usare il convertitore di livelli!: apro tom2pc.exe

Costruisco il file con estensione .TR4.

Prova...

OKAY! Finalmente funziona!!!

La modifica è stata l'aggiunta di una cornice di pavimento con l'erba attorno alla piattaforma.