Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
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
ForEach U As User In Users
If U.IsOnlineThen
U.Status="Connesso"
EndIf
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.
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 .
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 ... sei sempre un grande.
Ciao
Ultima modifica effettuata da Il Totem il 02/06/2009 alle 11:16
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
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.
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
PrivateSub ModificaArray()
Dim a AsInteger
Do
ReDim Preserve Users(a)
Users(a)= a.ToString
a += 1
Threading.Thread.Sleep(1)
Loop
EndSub
Non viene comunque sollevata nessuna eccezione.
Ciao.
Ultima modifica effettuata da Jeremy il 02/06/2009 alle 13:50