Forum - C# / VB.NET
- c# - indicizzatori per sortedlist di sortedlist di list di classe utente
Pagine: [ 1 2 ]
|
kenton (Normal User)
Newbie
Messaggi: 7
Iscritto: 31/10/2016
Ciao,
nel creare la seguente struttura per i dati ho degli errori.
E' una 'sortedlist' di una 'sortedlist' di una 'list' di una classe 'attivita' da me definita.
Per rendere agevole lettura e scrittura voglio mettere degli indicizzatori
in modo da accedere come fosse una matrice con le parentesi quadre,
agli oggetti interni.
Esempio:
Codice sorgente - presumibilmente C# / VB.NET
var matrice = new matrAttivita();
//inserire così
matrice["1A"]["John"] = {"math","3cat",30,""};
//leggere così
string materia = matrice["1A"]["John"][0].materia;
//e leggere anche così
string materia = matrice[0][0][0].materia;
//(override sui tipi?)
(so che mancano ancora tutti i controlli ai metodi per verificare l'esistenza o meno degli oggetti in lettura e scrittura)
Ho questo errore (in 4 punti, rige 36 40 59 63):
Errore CS0029 Non è possibile convertire in modo implicito il tipo
'System.Collections.Generic.SortedList<string, Estrazione_Excel01.listAttivita>'
in
'System.Collections.Generic.SortedList<string, System.Collections.Generic.SortedList<string, Estrazione_Excel01.listAttivita>>'
Cosa non ho capito ?
Codice sorgente - presumibilmente C#
public class matrAttivita
{
private SortedList
< string , SortedList
< string , listAttivita
>> _Inner
= new SortedList
< string , SortedList
< string , listAttivita
>> ( ) ;
public void Add( string corso, string insegnante, string materia, string ufc, ushort ore, string aulaLabo)
{
if ( ! _Inner.ContainsKey ( corso) )
_Inner.Add ( corso, null ) ;
if ( ! _Inner[ corso] .ContainsKey ( insegnante) )
_Inner[ corso] .Add ( insegnante, null ) ;
var last = _Inner[ corso] [ insegnante] .listAtt .Last ( ) ;
foreach ( Attivita att in _Inner[ corso] [ insegnante] .listAtt )
{
if ( att.materia == materia)
{
//errore materia già presente
break;
}
else
{
if ( att.Equals ( last) )
_Inner[ corso] [ insegnante] .Add ( materia, ufc, ore, aulaLabo) ;
}
}
}
public SortedList< string , SortedList< string , listAttivita>> this [ int i]
{
get
{
return _Inner.Values [ i] ; //<- errore
}
set
{
_Inner.Values [ i] = value; //<- errore
}
}
}
public class vectAttivita
{
public SortedList
< string , listAttivita
> _Inner
= new SortedList
< string , listAttivita
> ( ) ;
public void Add( string key)
{
_Inner.Add ( key, null ) ;
}
public SortedList< string , listAttivita> this [ int i]
{
get
{
return _Inner.Values [ i] ; //<- errore
}
set
{
_Inner.Values [ i] = value; //<- errore
}
}
}
public class listAttivita
{
public void Add( string materia, string ufc, ushort ore, string aulaLabo)
{
listAtt.
Add ( new Attivita
( materia, ufc, ore, aulaLabo
) ) ; }
public void Add( Attivita att)
{
listAtt.Add ( att) ;
}
public List< Attivita> this [ int i]
{
get
{
return listAtt;
}
set
{
listAtt = value;
}
}
}
public class Attivita
{
public string materia;
public string ufc;
public ushort ore;
public string aulaLab;
public Attivita( string materia, string ufc, ushort ore, string aulaLabo)
{
this .materia = materia;
this .ufc = ufc;
this .ore = ore;
this .aulaLab = aulaLabo;
}
}
Ultima modifica effettuata da kenton il 04/02/2017 alle 19:08
()
Newbie
Messaggi:
Iscritto:
Non saprei
kenton (Normal User)
Newbie
Messaggi: 7
Iscritto: 31/10/2016
Ok ho capito da solo ...
restituivo un livello di troppo nella dichiarazione degli indicizzatori ...
che stupidata, ero fermo qui da giorni ...
pfffff
Questo è il codice corretto,
righe 32 e 55
se può interessare ...
Codice sorgente - presumibilmente C#
public class matrAttivita
{
private SortedList
< string , SortedList
< string , listAttivita
>> _Inner
= new SortedList
< string , SortedList
< string , listAttivita
>> ( ) ;
public void Add( string corso, string insegnante, string materia, string ufc, ushort ore, string aulaLabo)
{
if ( ! _Inner.ContainsKey ( corso) )
_Inner.Add ( corso, null ) ;
if ( ! _Inner[ corso] .ContainsKey ( insegnante) )
_Inner[ corso] .Add ( insegnante, null ) ;
var last = _Inner[ corso] [ insegnante] .listAtt .Last ( ) ;
foreach ( Attivita att in _Inner[ corso] [ insegnante] .listAtt )
{
if ( att.materia == materia)
{
//errore materia già presente
break;
}
else
{
if ( att.Equals ( last) )
_Inner[ corso] [ insegnante] .Add ( materia, ufc, ore, aulaLabo) ;
}
}
}
public SortedList< string , listAttivita> this [ int i]
{
get
{
return _Inner.Values [ i] ;
}
set
{
_Inner.Values [ i] = value;
}
}
}
public class vectAttivita
{
public SortedList
< string , listAttivita
> _Inner
= new SortedList
< string , listAttivita
> ( ) ;
public void Add( string key)
{
_Inner.Add ( key, null ) ;
}
public listAttivita this [ int i]
{
get
{
return _Inner.Values [ i] ;
}
set
{
_Inner.Values [ i] = value;
}
}
}
public class listAttivita
{
public void Add( string materia, string ufc, ushort ore, string aulaLabo)
{
listAtt.
Add ( new Attivita
( materia, ufc, ore, aulaLabo
) ) ; }
public void Add( Attivita att)
{
listAtt.Add ( att) ;
}
public List< Attivita> this [ int i]
{
get
{
return listAtt;
}
set
{
listAtt = value;
}
}
}
public class Attivita
{
public string materia;
public string ufc;
public ushort ore;
public string aulaLab;
public Attivita( string materia, string ufc, ushort ore, string aulaLabo)
{
this .materia = materia;
this .ufc = ufc;
this .ore = ore;
this .aulaLab = aulaLabo;
}
}
Ultima modifica effettuata da kenton il 04/02/2017 alle 19:14
Poggi Marco (Member )
Guru
Messaggi: 969
Iscritto: 05/01/2010
Ciao !
Ho letto il tuo programma, e sinceramente, non ho capito completamente la sua funzionalità generale.
In ogni caso, la classe listAttivita andrebbe definita meglio:
Codice sorgente - presumibilmente C#
public class listAttivita
{
private List< Attivita> listAtt = null; // Aggiunta del campo listAtt
// Aggiunta di almeno un costruttore
public listAttivita( )
{
listAtt
= new List
< Attivita
> ( 10
) ; }
public void Add( string materia, string ufc, ushort ore, string aulaLabo)
{
listAtt.
Add ( new Attivita
( materia, ufc, ore, aulaLabo
) ) ; }
public void Add( Attivita att)
{
listAtt.Add ( att) ;
}
// Indicizzazione,
// Ho modificato alcune cose per renderlo "funzinante"
// In pratica, listAtt, per l' esterno si comporta come un vettore. Non so se nel tuo caso sia funzionale.
public Attivita this [ int i]
{
get
{
// Aggiungere controlli sull' indice.
// Lanciare un'eccezione se i sfora gli elementi caricati
return listAtt[ i] ;
}
set
{
// Aggiungere controlli sull' indice.
// Lanciare un'eccezione se i sfora gli elementi caricati o aumentare la capacità della lista.
listAtt[ i] = value;
}
}
}
kenton (Normal User)
Newbie
Messaggi: 7
Iscritto: 31/10/2016
Grazie Marco,
hai ragione listAttivita era proprio senza tutto ...
comunque è per memorizzare le ore di lezione (attivita) di una scuola
Quindi al primo livello ci sono le classi
al secondo livello gli insegnanti
al terzo la lista di materie di quella coppia classe-insegnante
e infine al quarto i dati di quella materia (attivita)
Se può interessare ho trovato questa guida c# molto dettagliata:
http://www.antoniopelleriti.it/ABCsharp%20guida%20alla%20p ...
Ho corretto gli indicizzatori leggendo lì.
Ultima modifica effettuata da kenton il 04/02/2017 alle 20:03
kenton (Normal User)
Newbie
Messaggi: 7
Iscritto: 31/10/2016
Che differenza c'è tra dichiarare il costruttore
Codice sorgente - presumibilmente C# / VB.NET
private List<Attivita> listAtt = null;
public listAttivita()
{
listAtt = new List<Attivita>(10);
}
oppure dichiarare il campo così:
Codice sorgente - presumibilmente C# / VB.NET
public List<Attivita> listAtt = new List<Attivita>();
e perché nel costruttore c'è (10) tra parentesi ?
Ultima modifica effettuata da kenton il 05/02/2017 alle 9:14
Poggi Marco (Member )
Guru
Messaggi: 969
Iscritto: 05/01/2010
La dichiarazione
Codice sorgente - presumibilmente C# / VB.NET
private List<Attivita> listAtt = null;
nomina listAtt come campo privato; impedisce l'utilizzo diretto della variabile all'esterno della classe.
Mentre
Codice sorgente - presumibilmente C# / VB.NET
listAtt = new List<Attivita>(10);
kenton (Normal User)
Newbie
Messaggi: 7
Iscritto: 31/10/2016
Ma perché dichiarare 10 elementi se tanto cresce da sola e di default occupa 0 poi 4 dopo il primo inserimento e poi cresce di valori pari nei successivi ...
Io pensavo di dichiarare
listAtt = new List<Attivita>();
Ultima modifica effettuata da kenton il 05/02/2017 alle 11:12
Thejuster (Admin )
Guru^2
Messaggi: 2297
Iscritto: 04/05/2008
Esattamente quoto Kenton.
Credo che sia un inutile spreco dichiarare una lista vuota con la capacità iniziale di 10 elementi vuoti.
Ovviamente se la lista non è inizializzata si ha sicuramente un Crash.
ma per come la vedo io, e molto più comodo inizializzare una lista vuota che una lista con 10 elementi vuoti.