Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - modifca insieme in ciclo for....each
Forum - C# / VB.NET - modifca insieme in ciclo for....each - Pagina 2

Pagine: [ 1 2 3 ] Precedente | Prossimo
Avatar
Jeremy (Normal User)
Pro


Messaggi: 134
Iscritto: 08/02/2009

Segnala al moderatore
Postato alle 17:45
Domenica, 31/05/2009
In allegato una piccola dimostrazione.

Facci sapere...
Ciao


Jeremy ha allegato un file: ArrayAndLinq.zip (101614 bytes)
Clicca qui per scaricare il file
PM Quote
Avatar
Il Totem (Admin)
Guru^2


Messaggi: 3635
Iscritto: 24/01/2006

Segnala al moderatore
Postato alle 10:20
Lunedì, 01/06/2009
Jeremy, quel codice non genera alcun errore. Se un elemento viene modificato, non è un problema, altrimenti non potremmo neanche fare questo, ad esempio:
Codice sorgente - presumibilmente VB.NET

  1. For Each U As User In Users
  2.   If U.IsOnline Then
  3.     U.Status = "Connesso"
  4.   End If
  5. Next


L'eccezione viene lanciata, ripeto, quando è la collezione ad essere modificata, ossia con operazioni di aggiunta, rimozione o inserimento. Inoltre, c'è un problema che non abbiamo considerato per questo metodo. Infatti, se i tuoi non sono stringhe ma oggetti, il Select di Linq si limita a selezionarli tutti e, poiché si tratta di valori di tipo reference, anche nella nuova collezione le variabili punteranno sempre agli stessi oggetti, con il risultato che se un elemento viene eliminato prima di essere letto, il suo riferimento non esisterà più. La logica soluzione sarebbe di usare la clonazione per effettuare una copia dell'oggetto in questione. Ma anche qui ci sono problemi: se l'oggetto non supporta l'interfaccia ICloneable, dovrai creare tu una funzione che esegue una copia intera dell'oggetto. Come se non bastasse, se l'oggetto ha come campi altri oggetti reference, bisogna considerare di clonare anche quelli, ossia bisogna effettuare una deep copy di tutto il grafo dell'oggetto. Questo risulterebbe in un carico eccessivo di memoria per il tuo processo, anche se si tratta di variabili temporanee.

PM Quote
Avatar
Jeremy (Normal User)
Pro


Messaggi: 134
Iscritto: 08/02/2009

Segnala al moderatore
Postato alle 10:42
Lunedì, 01/06/2009
Ciao Il Totem.
Il mio progettino di esempio, si riferiva al fatto di utilizzare l'interfaccia IEnumerable per il quale Goldberg ha fatto esplicito riferimento.
Il fatto che il mio codice non da errore non mi sembra una cosa da rimprovero :rofl: .
Lo scopo dell'esempio, non era produrre un errore, ma dimostrare una *possibile* e non assoluta soluzione.
Qualora gli elementi fossero riferimenti e non valori, bisognerebbe gestire l'eccezione NullReferenceException e considerare l'elemento *rimosso*, ma credo che, questa condizione, andrebbe gestita in ogni caso, a prescindere dalla tecnica che si utilizzi.
Non per fare polemica, ma che differenza c'è ad utilizzare il metodo Clone dell'interfaccia IClonable e utilizzare Linq a prescindere che l'oggetto sia IClonable o meno?
Ad ogni modo, anche se mi bacchetti sempre :noway: ... sei sempre un grande.
Ciao

Ultima modifica effettuata da Il Totem il 02/06/2009 alle 11:16
PM Quote
Avatar
GoLDBeRG (Ex-Member)
Expert


Messaggi: 331
Iscritto: 19/12/2005

Segnala al moderatore
Postato alle 15:36
Lunedì, 01/06/2009
ho reso piu stabile l'invio dei messaggi usando come ha detto il buon caro vecchio totem il .Clone...

ho fatto un thread a parte con un ciclo infinito e uno sleep di 1 secondo che mi clona l'array di user in un array temporaneo che sarà soggetto al ciclo e mentre sul temporaneo ci sono i cicli l'originale viene modificato senza dare alcun errore.....
il problema sorge solo se l'array originale viene copiato esattamente durante uno dei cicli... ma credo ahime che questo non possa evitarlo... mi faro' bastare questa soluzione

PM Quote
Avatar
Il Totem (Admin)
Guru^2


Messaggi: 3635
Iscritto: 24/01/2006

Segnala al moderatore
Postato alle 11:16
Martedì, 02/06/2009
Infatti, questo è un caso quanto meno singolare - criticare il fatto che non ci siano errori. Ma credevo volessi simulare la condizione in cui si trovava Goldberg, e quel codice non la rispecchiava, poiché si limita a modificare gli elementi della collezione, ma non la collezione stessa. Comunque pensavo che con IEnumerable, si riferisse all'enumerazione generalizzata di una collezione (con MoveNext e Current) e non al Linq, sebbene anche questo sia una soluzione possibile.
Per quanto riguarda il Close, ce n'è eccome di differenza: ho sperimentato sulla mia pelle quanto possa essere pericoloso sopravalutare Linq. Se tu con Linq selezioni gli oggetti di una collezione, ottieni sì una nuova collezione, ma formata sempre dagli stessi oggetti! Linq non clona i tipi reference, perciò anche avendo due variabili diverse, esse puntano alla stessa istanza, ed è questo che genera un errore. Invece, se nella query ci metti oggetti clonati, non ci sarà problema poiché i due saranno identici ma non uguali (nel senso che saranno due istanze diverse). Puoi vedere questo approccio nel programma GA Sequencer, nel metodo NextGeneration della classe GeneticEngine.

PM Quote
Avatar
Jeremy (Normal User)
Pro


Messaggi: 134
Iscritto: 08/02/2009

Segnala al moderatore
Postato alle 11:46
Martedì, 02/06/2009
Ciao Totem

Ti devo dare, ancora una volta, ragione su tutto quanto mi hai contestato.
:hail::hail:
:hail:

cerca di capire ... ho bisogno di ferie.

Ciao

Ultima modifica effettuata da Jeremy il 02/06/2009 alle 11:47
PM Quote
Avatar
GoLDBeRG (Ex-Member)
Expert


Messaggi: 331
Iscritto: 19/12/2005

Segnala al moderatore
Postato alle 12:59
Martedì, 02/06/2009
va bene ragazzi basta che ho risolto piu o meno... non penso di poter fare meglio di cosi per ora

PM Quote
Avatar
Jeremy (Normal User)
Pro


Messaggi: 134
Iscritto: 08/02/2009

Segnala al moderatore
Postato alle 13:42
Martedì, 02/06/2009
Fermo restando quanto detto da Il Totem.
Giusto per completezza, il progettino di esempio, avrebbe avuto senso,forse, se nella Routine ModificaArray, avessi redimensionato l'array.
Codice sorgente - presumibilmente VB.NET

  1. Private Sub ModificaArray()
  2.         Dim a As Integer
  3.         Do
  4.             ReDim Preserve Users(a)
  5.             Users(a) = a.ToString
  6.             a += 1
  7.             Threading.Thread.Sleep(1)
  8.         Loop
  9.     End Sub



Non viene comunque sollevata nessuna eccezione.
Ciao.


Ultima modifica effettuata da Jeremy il 02/06/2009 alle 13:50
PM Quote
Pagine: [ 1 2 3 ] Precedente | Prossimo