Newsgroup: it.comp.lang.visual-basic
Titolo: [vb.net] Due modi per archiviare dati da hashtable

Due modi di cui uno funziona ed uno no (Class1 contiene ID, Primo, 
Secondo).
Questo è il primo modo (nomi a caso):
Dim a1 As New Class1(1, "aaa" , "bbb")
Dim Hash As New Hashtable
Hash.Add(a1.ID, a1)
Questo è il secondo modo:
Public Hash as New Hashtable       'inserito nel modulo
Hash.Add(a1.ID, New Class1(1, "aaa" , "bbb")
Fin qui sembra che non ci siano problemi, invece credo che l'errore sia 
proprio prima delle seguenti istruzioni, che prelevano i dati:
Dim c As Class1 = CType(Hash(1), Class1)
textbox1.Text = c.Primo
Il primo modo funziona, il secondo no, il problema è che non posso usare 
il primo modo, devo assolutamente usare il secondo perchè ogni record 
inserito nell'hashtable prende l'ID dal contatore che ho inserito nel 
programma.
L'errore che mi dà il secondo modo è: "NullReferenceException - 
Riferimento a un oggetto non impostato su un'istanza di oggetto".
Christian

 programma.
Potresti postare *per intero* il codice usato nei due metodi e indicare 
*dove* ti da errore?
Il secondo sistema mi pare quantomeno bizzarro nel tuo contesto, a te la 
storia delle istanze proprio non ti entra in testa eh? :)
Ciao
-- 
Free .Net Reporting Tool - 
http://www.neodatatype.net
 

 storia delle istanze proprio non ti entra in testa eh? :)
Questa volta non credo che ci siano problemi di istanze, sia nel primo 
che nel secondo modo c'è un New Class1, no?  (maledette istanze  ;-) ).
Christian

 Hash.Add(a1.ID, New Class1(1, "aaa" , "bbb")
Se a1, non punta ad alcuna istanza della classe Class1, non potrà mai 
funzionare questo codice...
E, da quello che ho potuto vedere, è proprio così...
Ciao!
-- 
Gianluca Cannalire
Microsoft MVP/MCP - Visual Basic
http://www.visual-basic.it
http://community.visual-basic.it/gianluca
 

 E, da quello che ho potuto vedere, č proprio cosě...
Come mi consigli di modificarlo?
Christian

 E, da quello che ho potuto vedere, č proprio cosě...
Ho studiato un modo per far puntare a1 ad una nuova istanza della classe 
Class1, ma non trovo una metodologia corretta.
Ho anche cercato su MSDN, su libri, ma tutti danno come esempio il primo 
modo:
Dim a1 As New Class1(1, "aaa" , "bbb")
Dim Hash As New Hashtable
Hash.Add(a1.ID, a1)
Purtroppo a1 nel mio caso č una variabile e non posso usare il modo qui 
sopra descritto.
Sono graditi link, qualche dritta o la teoria utile per risolvere il 
problema.
Christian

 sopra descritto.
Perchè, cos'hai contro le variabili?
Ciao 

programma.
Che, sinceramente, non ho capito cosa vuoi dire, in particolare la parte 
"...prende l'ID dal contatore che ho inserito  nelprogramma."
Ciao


Fabio says...

A me piacciono molto le variabili   ;-)   ma in questo caso non mi sono 
utili.
Dim a1 As New Class1(1, "aaa" , "bbb")
Dim Hash As New Hashtable
Hash.Add(a1.ID, a1)
Il codice qui è semplificato, in realtà al posto di a1 metterò un 
contatore che si incrementa di 1 ad ogni nuova hashtable.
A meno che tu non conosca un modo per creare tante variabili quante ne 
decide l'utente, è necessario trovare un altro modo per archiviare i 
vari hashtable, o modificando quello che ho fatto io costruendolo in 
modo che funzioni:
Public Hash as New Hashtable       'inserito nel modulo
Hash.Add(a1.ID, New Class1(1, "aaa" , "bbb")
oppure qualcosa di diverso.
Se non riesco a farlo funzionare sono costretto a tornare indietro ad 
una matrice bidimensionale, ma non lo vorrei fare.
Christian

 contatore che si incrementa di 1 ad ogni nuova hashtable.
Io farei così (se ho capito bene il problema)
Dim Hash As New Hashtable
...
' Se il primo parametro è il contatore lo togliamo.
Dim a1 As New Class1("aaa" , "bbb")
Hash.Add(a1.ID, a1)
in Class1
private shared _contatore as integer = 0
private _id as integer
public sub New(byval p1 as string, byval p2 as string)
    _contatore += 1
    _id = _contatore
end sub
public property readonly Id as integer
    get
        return _id
    end get
end property
Così il contatore se lo smazza la Classe1 stessa in modo trasparente.


 "...prende l'ID dal contatore che ho inserito  nelprogramma."
Mi spiego meglio: l'utente inserisce dei dati, quando vuole salvarli io 
apro una nuova hashtable per memorizzarli. Poi inserisce altri dati ed 
al momento del salvataggio apro una seconda hashtable e così via. Come 
ID della hashtable uso un contatore che s'incrementa di 1 ogni volta che 
l'utente salva dei dati.
Con questo codice:
Dim a1 As New Class1(1, "aaa" , "bbb")
Dim Hash As New Hashtable
Hash.Add(a1.ID, a1)
non posso fare come voglio io perchè "Dim a1..." non è incrementabile di 
uno ad ogni nuova hashtable.
Con quest'altro codice invece:
Public Hash as New Hashtable       'inserito nel modulo
Hash.Add(a1.ID, New Class1(1, "aaa" , "bbb")
posso utilizzare a1 come variabile che s'incrementa di 1 ogni volta, ma 
non funziona, quindi è necessario o modificare quest'ultima riga 
affinchè funzioni, oppure scrivere altro codice diverso.
Spero d'essere stato chiaro, in caso contrario chiedi pure.
Christian

 Così il contatore se lo smazza la Classe1 stessa in modo trasparente.
Molto interessante, l'ho implementato per vedere se funziona (readonly 
va prima di property   ;-)  ).
Correggimi se sbaglio. Il principio che ti ha guidato è: se non riesco a 
fare tante Dim, allora farò una dim gigantesca con l'ID che s'incrementa 
di 1 ogni volta.
Alcune note:
- a cosa servono p1 e p2 nella sub new? Non mi sembra che vengano usate, 
ma vedo che vengono proposte come seconda scelta nella Class1;
- il contatore non s'incrementa, infatti dà questo errore:
"System.ArgumentException" L'elemento è già stato aggiunto. Chiave nel 
dizionario: "0". Chiave aggiunta "0"
Ho provato a spostare le due righe del contatore nella readonly, ma 
s'incrementa in modo esponenziale e comunque ricopia i dati nuovi sopra 
quelli vecchi.
Ho anche provato a togliere p1 e p2, ma non funziona ancora.
Ti prego di seguirmi e di correggere le imperfezioni perchè queste 
informazioni sono interessanti ma al momento non funzionano bene.
Christian

 farò una dim gigantesca [...]
Dio ci salvi.
Lokar 

 Dio ci salvi.
:)
Sarà una dImmane!
Ciao 

Fabio says...

Allora non ho capito: qual'è il principio che ti ha portato ad indicarmi 
quel codice?
E perchè non funziona?
Christian

 E perchè non funziona?
veramente funziona perfettamente :)
E' ovvio che p1 e p2 sono i parametri che *tu* hai indicato nel tuo codice 
(io mica so cosa sono e li ho chiamati così per semplifcicarti le cose) e 
che se usassi lo stesso codice da *te* postato vedresti che funziona.
Ciao 

 che se usassi lo stesso codice da *te* postato vedresti che funziona.
Eh, adesso ho capito l'errore fatto nell'implementazione del tuo codice. 
Abbia pazienza, sto crescendo ed ogni giorno imparo qualcosa di nuovo, 
anche grazie a questo ng.
Adesso non c'č piů l'errore ed il programma legge in modo corretto le 
righe di codice scritte.
Nel passaggio successivo perň se con questo codice prima tutto 
funzionava bene:
Dim a1 As New Class1(1, "aaa" , "bbb")
Dim Hash As New Hashtable
Hash.Add(a1.ID, a1)
Dim c As Class1 = CType(Hash(1), Class1)
textbox1.Text = c.p1
adesso con la nuova classe c'č un errore qui:
Dim c As Class1 = CType(Hash(1), Class1)
Non occorre che posto il tipo di errore, č sufficiente dire che  c  non 
si riempie.
Bisogna modificare qualcosa in quella riga per renderla compatibile con 
la classe modificata?
Christian

 compatibile con la classe modificata?
Non occorre che posto una risposta esaustiva, è sufficiente
dire "si".
Lokar
P.S. Semmai volessi decidere di spiegare COSA vuoi fare, piuttosto
che buttarti a scrivere codice "nonsense", saro' lieto di aiutarti.

 piuttosto che buttarti a scrivere codice "nonsense", saro' lieto di aiutarti.
Addendum (visto che la perspicacia non sembra essere una tua
dote primaria primaria):
Com'e' fatta la classe Class1 lo sai solo tu, e a meno che
posti il codice e cerchi di spiegare "in italiano" quello
che vuoi fare, dubito che qualcuno qui possa darti la
"giusta dritta" che cerchi.
Se avessi perso DIECI MINUTI a descrivere meglio il problema
nel primo post, probabilmente non sarebbero passati 3 giorni
senza soluzione.
hth,
Lokar

Lokar says...

Se hai seguito tutto il thread dovresti avere tutte le informazioni che 
ti servono, ma visto che sei così gentile da darmi una mano, lo riposto 
volentieri (sono 13 campi, ne posto solo 2 per semplicità e con nomi 
semplici) (comprendono ovviamente le modifiche di Fabio):
Public Class Class1
Private _P1 As String
Private _P2 As String
Public Sub New(ByVal p1 As String, ByVal p2 As String)
   Me.P1 = p1
   Me.P2 = p2
   _Contatore += 1
   _ID = _Contatore
End Sub
Private Shared _Contatore As Integer = 0
Private _ID As Integer
Public ReadOnly Property id() As Integer
   Get
      Return _ID
   End Get
End Property
Public Property P1() As String
   Get
      Return Me._P1
   End Get
   Set(ByVal Value As String)
      Me._P1 = Value
   End Set
End Property
Public Property P2()...   <--- lo stesso di P1
End Class

 [SNIP]
Molto bene, siamo a meta' dell'opera.
Ora. In parole semplici. Cosa vuoi fare? Cosa vuoi _ottenere_?
Tralascia il COME, per favore.
Lokar 

Lokar says...

Archiviazione di dati (più semplice di così...   ;-)  ).
Ogni gruppo di 2 dati (nell'esempio) ha il suo contatore per ricerche 
veloci, modifiche e cancellazioni, cosa che non ho ancora provato a fare 
ma che non credo d'avere problemi.
Se sarà il caso implementerò anche IComparable, in caso contrario sarà a 
posto così.
Christian

 fare ma che non credo d'avere problemi.
Scusami,
ma utilizzare un DataTable, non sarebbe più semplice???
Ciao


 ma utilizzare un DataTable, non sarebbe più semplice???
Quando un paio di settimane fa ho chiesto qual'è la soluzione migliore 
di archiviare dati bidimensionali con facile ricerca dei dati mi è stato 
risposto "hashtable" .....
E poi sono curioso di sapere perchè questa riga di codice:
Dim c As Class1 = CType(Hash(1), Class1)
con le modifiche (utili, ci mancherebbe) di Fabio non preleva più i dati 
archiviati.
Christian

 Archiviazione di dati (più semplice di così...   ;-)  ).
Chiedo scusa, l'archiviazione è già stata implementata.
Ora mi serve prelevare i dati per farci modifiche, cancellazioni ecc.
Prima delle (utili) modifiche di Fabio alla classe, questa riga 
funzionava:
Dim c As Class1 = CType(Hash(1), Class1)
Ora non più e vorrei che funzionasse, oppure un altro sistema per 
prelevare i dati archiviati.
Christian

 dati archiviati.
Beh, fondamentalmente il motivo è che non bisogna limitarsi a copiare 
quello che viene suggerito, ma a capire...
Comunque, dato che dici che la riga Dim c As Class1 = CType(Hash(1), 
Class1) non genera errore, ma restituisce un oggetto vuoto, è 
semplicemente dovuto al fatto che nel costruttore, non valorizzi i fields 
privati.
Ecco, "copia" questo codice:
Public Class Class1
    Private Shared _contatore As Integer = 0
    Private _id As Integer
    Public Sub New(ByVal p1 As String, ByVal p2 As String)
        _contatore += 1
        _id = _contatore
        _p1 = p1
        _p2 = p2
    End Sub
    Public ReadOnly Property Id() As Integer
        Get
            Return _id
        End Get
    End Property
    Private _p2 As String
    Public Property ValueA() As String
        Get
            Return _p2
        End Get
        Set(ByVal value As String)
            _p2 = value
        End Set
    End Property
    Private _p1 As String
    Public Property ValueB() As String
        Get
            Return _p1
        End Get
        Set(ByVal value As String)
            _p1 = value
        End Set
    End Property
End Class
E questo è il test:
Dim ht As New Hashtable
Dim a1 As New Class1("aaa", "bbb")
ht.Add(a1.Id, a1)
Dim c As Class1 = CType(ht(1), Class1)
Debug.WriteLine(c.ValueA & " " & c.ValueB)
Ciao!


 Dim c As Class1 = CType(Hash(1), Class1)
Esiste l'elemento 1? Ancora non hai scritto quale errore
viene sollevato nel tentare di effettuare la conversione.
hth,
Lokar

 Private _p1 As String
Ciao Gianluca, scusa la domanda decisamente OT, sono solo curioso.
Per quale motivo hai inserito i parametri in ordine decrescente? =)
So che e' una domanda insensata, forse e' stato solo per fretta,
ma mi e' sorta la curiosita' :)
Lokar 

Lokar wrote:

Non ha nessuna importanza l'ordine delle property...
Stavo scrivendo il codice mentre cercavo di addormentare il mio piccolo 
Diego, e quindi non è che prestassi molta attenzione a quello che scrivevo 
:)))


 attenzione a quello che scrivevo  :)))
Ognuno di noi ha qualche "fissa" nella stesura del codice.
Ho solo pensato che ad esempio normalmente leggessi le
classi dal basso verso l'alto e che quindi sei solito
mettere le proprieta' in un certo ordine o una amenita'
del genere... Capita =)
Una coccola al pupo (mio omonimo) da parte mia =)
Lokar/Diego 

 viene sollevato nel tentare di effettuare la conversione.
Dopo la riga di codice da te quotata la variabile in questione (c) 
rimane vuota e nel momento in cui tento di scrivere un dato:
textbox1.Text = c.P1
mi dà questo errore:
"System.NullReferenceException... Riferimento a un oggetto non impostato 
su un'istanza di oggetto".
Ovviamente lo dà perchè c è vuota, quindi l'errore è proprio nella riga 
di codice da te quotata.
Christian

 ricevere l'aiuto adeguato, ne' IMHO capirci niente neanche tu.
Forse a Christian conviene riordinare le idee e postare un nuovo thread, 
questo inizia ad essere illeggibile.
Poi occorrerebbe prestare un po' di attenzione nella terminologia.
Dire che
Dim c As Class1 = CType(Hash(1), Class1)
va in errore e c non si riempie non č molto chiaro: o va in errore o c non 
"si riempie", ma "non si riempie" significa che c č nothing o che c ha i 
campi non valorizzati?
In Hash(1) cosa c'č?
Un minimo di debug "on your own" occorre imparare a farlo.
Ciao 

 ...
Perchè dichiaro privato P1 e poi nella pubblica metti un nome diverso 
invece che dichiarare subito pubblico P1?
Grazie per le delucidazioni che mi vorrai dare.
Christian

 questo inizia ad essere illeggibile.
In effetti inizia ad essere troppo lungo, ma mi occorre aprire altri 
threads perchè il problema è stato risolto.
Grazie a tutti per l'aiuto.
Christian

 Grazie per le delucidazioni che mi vorrai dare.
Prego ;)


 ogni volta che lo nomino...)
E chi se la prende, io sono qua per imparare.
Il libro ce l'ho e lo so facendo mio (versione 2003), ma è bello 
grosso...
Christian