Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Salve sono nuovo del forum e anche di VB.NET che sto studiando (purtroppo nei ritagli di tempo) sull’ottima guida di Totem. Chiedo scusa in anticipo per la prolissità ma ho 2 problemi che non riesco proprio a risolvere. Se qualcuno volesse darmi una mano….
Sono alle prese con gli hastable e i metodi factory. Ho creato programmino che calcola il peso di alcuni cubi. C’è una classe cube con 3 campi private (e relative property) : Spigolo, Densità e l’hastable Cubes (Shared oltre che private). Dal main vengono creati alcuni oggetti A, B, C ecc. di tipo cube, inizializzati attraverso un metodo factory. La mia prima domanda è la seguente:
1) Perché il costruttore (richiamato dal metodo factory) va scritto
Private Sub New(ByVal Spig As Single, ByVal Ps As Single)
Me._Spig = Spig
Me._Ps = Ps
_cubes.Add(Spig, Me)
End Sub
'Non sarebbe sufficiente scrivere (eliminando il riferimento alla classe stessa “Me” ) ?
Private Sub New(ByVal Sp As Single, ByVal Ps As Single)
Spig = Sp
Ps = Ps
cubes.Add(Spig, Ps)
End Sub
La seconda domanda è la seguente:
2) Se voglio visualizzare tutto l’hashtable cioè tutti i cubi dalla main, scrivo questo codice e funziona
For Each X As DictionaryEntry In cube.cubes
Dim Y As cube = X.Value
Console.WriteLine(Y.Spig)
Console.WriteLine(Y.Ps)
Console.WriteLine()
Next
Ma se voglio visualizzare un cubo solo richiamandolo per chiave (spigolo) non so come fare. Per es per visualizzare il cubo di spigolo 1 ho provato con
Dim H As Hashtable = cube.cubes
Console.WriteLine(H(1.0))
Cioè dichiarando un hashtable inizializzandolo col nostro hashtable e andando a visualizzare l’elento richiesto. Ma che c’è che non va ?
Oppure con
Dim Y As cube = cube.cubes(3.0)
Console.WriteLine("Cubo A: " & Y.Ps)
D’altronde si tratta di un hashtable shared di oggetti cube. Quindi dichiaro l’oggetto Y, lo inzializzo con l’elemento dell’hashtable desiderato e poi vado a visualizzarlo. Perché non deve funzionare ?
Ultima modifica effettuata da Il Totem il 30/08/2010 alle 10:55
Grazie per la chiarezza (consueta, del resto) riguardo alla risposta al punto 1.
Per quanto riguarda la seconda domanda
Allora: se uso la soluzione
Dim H As Hashtable = cube.cubes
Console.WriteLine("Cubo A: " & H(1.0).Ps)
si genera il messaggio di errore "Variabile oggetto o variabile del blocco With non impostata."
se invece uso la
Dim Y As cube = cube.cubes(3.0)
Console.WriteLine("Cubo E: " & Y.Ps)
ottengo "Riferimento a un oggetto non impostato su un'istanza di oggetto."
D'altronde ho ragionato così: ho un'hashtable di oggetti cube, richiamo quello che mi interessa e poi mando a video il campo Ps (il campo spigolo l'ho usato come chiave. Non ha molto senso ma è solo un programma di prova)
Comunque ad evitare ogni possibile frintendimento, posto di seguito il sorgente o è preferibile che si invii il tutto in archivio .zip ?
Codice sorgente - presumibilmente VB.NET
Module Module1
Class cube
Private _Spig, _Ps As Single
PrivateShared _cubes AsNew Hashtable
ReadOnlyProperty Spig()As Single
Get
Return _Spig
EndGet
EndProperty
ReadOnlyProperty Ps()As Single
Get
Return _Ps
EndGet
EndProperty
SharedReadOnlyProperty cubes()As Hashtable
Get
Return _cubes
EndGet
EndProperty
PrivateSubNew(ByVal Spig As Single, ByVal Ps As Single)
Me._Spig = Spig
Me._Ps = Ps
_cubes.Add(Spig, Me)
'IN ALTERNATIVA _cubes.Add(Spig, Ps)
EndSub
PublicSharedFunction create(ByVal Spig As Single, ByVal Ps As Single)As cube
Ho convertito il tuo codice in C# perchè ora sono su linux e mi manca vbc. Ho riscontrato che il for stampa i valori corretti, ma nel formato sbagliato. Stampa 1, non 1.0. Ciò significa che l'oggetto contenuto nello spazio dedicato _Spig non è un Single, ma piuttosto un Integer. Poiché la chiave di ricerca è un double (3.0 è double, 3.0F single), il match non sussiste. Una possibile causa dell'errore potrebbe risiedere nel fatto che usi Hashtable, ossia una versione a tipizzazione debole del tipo Dictionary. Come avrai già letto, ciò implica che ogni valore e chiave è mappato in una variabile di tipo object tramite boxing, il che potrebbe far perdere al dato immesso la sua propria natura a causa di conversioni implicite. Inoltre, sempre perchè le chiavi sono mappate da objects, quindi oggetti reference, posso presumere che il confronto avvenga per riferimento.
Una soluzione sarebbe quella di usare la versione a tipizzazione forte, Dictionary(Of T, K), con l'ausilio dei generics. Questo è un possibile esempio del perchè le chiavi di tipo floating point siano da evitare (il caso per eccellenza sarebbe l'errore di approssimazione).
Ok. Siccome sto studiando (pochissimo: ci metterò 2 anni a finire il tuo corso fra occupazioni di lavoro e bambini) e il programma è di prova, ho provato ad adottare una chiave stringa.
Fnziona tutto: il for, che tuttavia mi sembrava funzionasse (in VB) bene anche prima e anche le ricerche "secche" di un singolo elemento che poi era ciò che mi interessave maggiormente: vedere se le maniere che avevo pensato per richiamare un elemento singolo dell'hashtable funzionavano. Ok, a patto di avere una stringa come chiave.
Una chiave stringa nell'hashtable è un classico, ma questo tipo è comunque progettato per accettare un qualsiasi tipo di chiave. Quando arriverai a leggere i generics, potrai approfittarne.
1) Non è necessario scrivere il costruttore nel primo modo, né è più corretto nel secondo. Entrambi hanno sia pregi che difetti. Il primo ha il vanto di accedere direttamente ai campi privati, senza passare per le proprietà: questo favorisce un'interazione più diretta e veloce con i dati, specialmente nel caso tali proprietà contengano molto codice di controllo. Inoltre, dato che il costruttore è privato e viene richiamato da un metodo factory è ragionevole supporre che suddetto metodo abbia controllato in anticipo il valore dei parametri, verificando che sia coerente, dato che è proprio questa l'utilità dei metodi factory. Il secondo, al contrario, è meno diretto, ma può comunque gestire valori erronei dei parametri, anche se, come già detto, è un'operazione superflua in un metodo factory.
2) E' quello che mi chiedo anche io, perchè non dovrebbe? Tu non hai postato, però, l'output che ottieni richiamando quel codice, o l'eccezione che viene generata, quindi non posso sapere qual è il problema.