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 - [VB.NET] Magheggi strani di VB con le variabili
Forum - C# / VB.NET - [VB.NET] Magheggi strani di VB con le variabili

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
Qwertj (Dev Team)
Guru


Messaggi: 678
Iscritto: 30/05/2011

Segnala al moderatore
Postato alle 21:19
Venerdì, 22/07/2011
Questo topic è stato chiuso dal moderatore

Salve a tutti,
Non mi riesco assolutamente a spiegare una cosa:
Nel mio programma chiamo una funzione che accetta due parametri ByVal, glieli passo entrambi. Uno di questi è una lista, quando gliela passo però viene passata invece che come ByVal, come ByRef, e viene modificata. Nonostante sia una proprietà ReadOnly :om:
Il codice è circa questo
Codice sorgente - presumibilmente VB.NET

  1. 'Funzione chiamata
  2. Private Function DoSomething(ByVal List1 As List(Of String), ByVal List2 As List(Of String)) As String
  3. Dim Result As String
  4. List1.RemoveRange(0, List2.Count)
  5. For Each Element As String In List1
  6.   Result &= Element
  7. Next
  8. Return Result
  9. End Function
  10.  
  11. 'metodo "principale"
  12. Public Sub DoSomethingElse(ByVal List2 As List(Of String))
  13. Dim AnObject As New AClass("example")
  14. 'questo stampa, ad esempio, 7
  15. MessageBox.Show(AnObject.ReadOnlyList.Count)
  16. MessageBox.Show(DoSomething(AnObject.ReadOnlyList, List2))
  17. 'questo stampa invece 0 quando List2.Count = AnObject.ReadOnlyList.Count
  18. MessageBox.Show(AnObject.ReadOnlyList.Count)
  19. End Sub


Ha un senso?:-|

PM
Avatar
BionicGod (Normal User)
Rookie


Messaggi: 33
Iscritto: 16/06/2011

Segnala al moderatore
Postato alle 21:27
Venerdì, 22/07/2011
Che ne dici di postare tutto il sorgente...
Non so cosa sia AClass, non ho il suo funzionamento, come faccio ad aiutarti?
POSTA TUTTO...

PM
Avatar
Qwertj (Dev Team)
Guru


Messaggi: 678
Iscritto: 30/05/2011

Segnala al moderatore
Postato alle 22:08
Venerdì, 22/07/2011
Il problema non sta sicuramente in AClass, ma piuttosto nel codice che ti ho postato

Comunque, se vuoi anche quelli te li do, ma dubito che possano aiutarti
Codice sorgente - presumibilmente VB.NET

  1. Class AClass
  2. Public Sub New(ByVal Value As String)
  3.      For Each Letter As Char in Value
  4.           _ReadOnlyList.Add(Letter.ToString)
  5.      Next
  6. End Sub
  7.  
  8. Private _ReadOnlyList As New List(Of String)
  9. Public ReadOnly Property ReadOnlyList As List(Of String)
  10.      Return _ReadOnlyList
  11. End Property
  12. End Class


Ultima modifica effettuata da Qwertj il 22/07/2011 alle 22:10
PM
Avatar
BionicGod (Normal User)
Rookie


Messaggi: 33
Iscritto: 16/06/2011

Segnala al moderatore
Postato alle 22:37
Venerdì, 22/07/2011
Codice sorgente - presumibilmente VB.NET

  1. Public Sub DoSomethingElse(ByVal List2 As List(Of String))
  2.         Dim AnObject As New AClass("example")
  3.         Console.WriteLine(AnObject.ReadOnlyList.Count)
  4.         Dim e As New List(Of String)
  5.         For Each Letter As Char In AnObject.ReadOnlyList
  6.             e.Add(Letter.ToString)
  7.         Next
  8.         Console.WriteLine(DoSomething(e, List2))
  9.         Console.WriteLine(AnObject.ReadOnlyList.Count)
  10.     End Sub


La soluzione sarebbe creare un'altra lista così da non alterare il numero di valori in ReadOnlyList
Rimane comunque anomala la modifica nonostante sia ReadOnly.
Non so che dirti...

PM
Avatar
Qwertj (Dev Team)
Guru


Messaggi: 678
Iscritto: 30/05/2011

Segnala al moderatore
Postato alle 22:47
Venerdì, 22/07/2011
Infatti... è davvero strano :yup:

PM
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2765
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 1:59
Sabato, 23/07/2011

Se tu sapessi vagamente come funziona il linguaggio che stai usando, avresti ben chiaro il motivo per cui le liste (ed in generale tutti gli oggetti) vengono passati ByRef. Inoltre, se avessi studiato la differenza tra oggetti mutabili ed immutabili, sapresti immediatamente come risolvere questo "problema" che in realtà è il comportamento normale del codice.






PM
Avatar
BionicGod (Normal User)
Rookie


Messaggi: 33
Iscritto: 16/06/2011

Segnala al moderatore
Postato alle 9:09
Sabato, 23/07/2011
Premetto che io non studio VB.NET, ma C#...però non ho mai sentito parlare di oggetti mutabili e immutabili. Siceramente nel libro di programmazione non ci sono riferimenti a questi termini. Potresti gentilmente spiegarci come funzionano?

PM
Avatar
Qwertj (Dev Team)
Guru


Messaggi: 678
Iscritto: 30/05/2011

Segnala al moderatore
Postato alle 9:27
Sabato, 23/07/2011
In effetti hai ragione HeDo, mi ero scordato che gli oggetti reference sono passati per referenza 8-| Chiedo umilmente perdono :hail:
Però come risolvo? Che sono gli oggetti mutabili/immutabili?
Avevo provato anche a fare una cosa così:
Codice sorgente - presumibilmente C# / VB.NET

  1. Dim Copy As List(Of String) = List1.Take(List1.Count).ToList


Anche una cosa del genere passa a Copy una referenza di List1?

PM
Avatar
HeDo (Founder Member)
Guru^2


Messaggi: 2765
Iscritto: 21/09/2007

Segnala al moderatore
Postato alle 10:37
Sabato, 23/07/2011
Testo quotato

Postato originariamente da Qwertj:

In effetti hai ragione HeDo, mi ero scordato che gli oggetti reference sono passati per referenza 8-| Chiedo umilmente perdono :hail:
Però come risolvo? Che sono gli oggetti mutabili/immutabili?
Avevo provato anche a fare una cosa così:
Codice sorgente - presumibilmente C# / VB.NET

  1. Dim Copy As List(Of String) = List1.Take(List1.Count).ToList


Anche una cosa del genere passa a Copy una referenza di List1?



il modo migliore per fare una cosa del genere se vuoi impedire che si modifichi la lista ma NON ti serve effettivamente una lista ma solo un array: passa un IEnumerable<T> (con T il tipo della lista). In questo modo la funzione si vedrà arrivare un insieme enumerabile senza avere la possibilità di moficarla.

Se invece ti serve passare una lista che la funzione può modificare ma senza che i cambiamenti si riflettano sulla lista del chiamante, l'unico modo è istanziarne una nuova:

Codice sorgente - presumibilmente C# / VB.NET

  1. void foo(List<int> lst) {
  2.  
  3.     ....
  4.     lst.Add(1);
  5.     ...
  6. }
  7.  
  8. List<int> callerList = new List<int>();
  9.  
  10. // Chiami la funzione istanziando una nuova lista
  11. foo(new List<int>(callerList));



ricordati però che un approccio di questo genere genera una shallow copy, non una copia profonda dell'oggetto. Il risultato è che se la lista è una lista di oggetti mutabili e il chiamato modifica uno di questi oggetti, i cambiamenti si ripercuoteranno sul chiamante. Il motivo è che in una lista di oggetti si memorizzano i reference agli oggetti :)

PM
Pagine: [ 1 2 ] Precedente | Prossimo