Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it
    Registrato dal
    Apr 2006
    Messaggi
    87

    [vb .net] tipi riferimento

    Ciao a tutti,
    vorrei avere delle spiegazioni a riguardo questo codice:

    private sub popolaDataSet(byref ds as dataset)
    ' Il dataset viene popolato
    '....
    end sub

    private fuction ottieniDataSet() as dataset
    dim ds as dataset
    ' Il dataset viene popolato
    '...

    return ds
    end function

    A questo punto ho la scelta di utilizzare 2 possibilità per avere un dataset popolato: passarlo come riferimento oppure assegnare il dataset di ritorno ad una var.
    Ma qual è il metodo più performante? O forse sono uguali?

  2. #2
    Per le performance non saprei risponderti, la differenza credo sia talmente piccola che proprio non so quale potrebbe essere piu' veloce...
    Ti posso pero' dire questo:
    - con "(byref ds as dataset)" passi un oggetto esistente
    - con "private fuction ottieniDataSet() as dataset" crei un nuovo oggetto e quinid utilizzi sicuramente piu' risorse

    Quindi, io personalmente ti consiglio di utilizzare "byref"... ma e' solo il mio parere personale...
    Se cercate un software visitate il sito della mia software house
    Hobby Vitual: il nuovo sito per tutti i collezionisti!

  3. #3
    Utente di HTML.it
    Registrato dal
    Apr 2006
    Messaggi
    87
    Ok, grazie mille

  4. #4
    Originariamente inviato da simon78_soft
    Per le performance non saprei risponderti, la differenza credo sia talmente piccola che proprio non so quale potrebbe essere piu' veloce...
    Ti posso pero' dire questo:
    - con "(byref ds as dataset)" passi un oggetto esistente
    - con "private fuction ottieniDataSet() as dataset" crei un nuovo oggetto e quinid utilizzi sicuramente piu' risorse

    Quindi, io personalmente ti consiglio di utilizzare "byref"... ma e' solo il mio parere personale...
    Guarda che non è assolutamente vero... anzi, il ByRef è leggerissimissimamente più lento: infatti quando passi un oggetto ByVal ad una funzione tu in realtà stai passando un puntatore a tale oggetto (che è fisicamente allocato nell'heap), per cui che tu lo passi per valore (creando una copia del puntatore sullo stack - consumo di memoria: 4 byte) o che tu lo passi per riferimento (creando un puntatore che punta al puntatore all'oggetto, identico consumo di memoria) la differenza di impiego di memoria è nulla. Dico che il ByRef è leggerissimissimamente più lento perché per accedere all'oggetto stesso è necessario dereferenziare due puntatori al posto di uno; inoltre semanticamente è più corretto che l'oggetto da ottenere venga restituito come valore di ritorno.
    In ogni caso le tue considerazioni risultano corrette se parliamo di strutture (Struct), che vengono allocate sullo stack e non sull'heap.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it
    Registrato dal
    Apr 2006
    Messaggi
    87
    Forse non ho ben capito, ma quando passi un oggetto (classe) ad una funzione utilizzando byval , in realtà viene copiato il puntatore all'oggetto nello stack, giusto?
    Mentre se viene passato utlizzando byref viene creato un puntatore (ma dove? nello stack?) al puntatore dell'oggetto.

  6. #6
    Esatto; in sostanza viene sempre e comunque passato un puntatore, solo che in un caso tale puntatore punta direttamente all'oggetto, nel secondo punta al puntatore all'oggetto che è stato passato come parametro della funzione.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Apr 2006
    Messaggi
    87
    Ma nel caso di byval il puntatore all'oggetto viene copiato nello stack, mentre nel caso di byref il puntatore al puntatore dell'oggetto dove viene creato? anche nello stack?
    Quello che non capisco è che se vengono comunque passati dei puntatori, perchè con byval all'uscita della routine le modifiche all'oggetto vengono perse?

  8. #8
    Originariamente inviato da pol86
    Ma nel caso di byval il puntatore all'oggetto viene copiato nello stack, mentre nel caso di byref il puntatore al puntatore dell'oggetto dove viene creato? anche nello stack?
    Certo, tutti i parametri passati alle funzioni stanno sullo stack.
    Quello che non capisco è che se vengono comunque passati dei puntatori, perchè con byval all'uscita della routine le modifiche all'oggetto vengono perse?
    Infatti con ByVal le modifiche all'oggetto NON vengono perse (a meno, come già detto, che non si tratti di una struttura e non di una classe).
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Utente di HTML.it
    Registrato dal
    Apr 2006
    Messaggi
    87
    Con ByVal, il parametro viene passato come valore (alla funzione viene passata una copia della variabile), eventuali modifiche apportate alla copia non influiscono sul valore della variabile originale passata come parametro.

  10. #10
    Certo, ma siccome la variabile è un puntatore (essendo gli oggetti dei Reference Types) questo non ti impedisce di modificare l'oggetto a cui punta; l'unica differenza funzionale che si avverte passando un oggetto ByVal o ByRef è che, passandolo ByVal, non puoi modificare il valore del puntatore, ossia non puoi assegnare un oggetto diverso al puntatore (o meglio, puoi ma tale modifica non si ripercuote sul codice chiamante). Prova quest'esempio:
    codice:
    Public Class Test
        Public CampoEsempio As Integer
        Public ReadOnly Name As String 'Campo immutabile
        Public Sub New(ByVal nName As String)
            Name = nName
            Console.WriteLine("Costruzione di " & Me.ToString())
        End Sub
        Public Overrides Function ToString() As String
            Return "{Name=" & Name & ";CampoEsempio=" & CampoEsempio.ToString() & "}"
        End Function
        Protected Overrides Sub Finalize()
            Console.WriteLine("Distruzione di " & Me.ToString())
        End Sub
    End Class
    
    Public Module Principale
        Public tst As New Test("Test creato in Main")
        Public Sub Main()
            tst.CampoEsempio = 0
            EsempioByVal1(tst)
            Console.WriteLine(tst)
            EsempioByRef1(tst)
            Console.WriteLine(tst)
            EsempioByVal2(tst)
            Console.WriteLine(tst)
            EsempioByRef2(tst)
            Console.WriteLine(tst)
            EsempioByVal3(tst)
            EsempioByRef3(tst)
        End Sub
    
        Public Sub EsempioByVal1(ByVal parametro As Test)
            Console.WriteLine("In EsempioByVal1")
            parametro.CampoEsempio += 5
        End Sub
    
        Public Sub EsempioByRef1(ByRef parametro As Test)
            Console.WriteLine("In EsempioByRef1")
            parametro.CampoEsempio += 5
        End Sub
        Public Sub EsempioByVal2(ByVal parametro As Test)
            Console.WriteLine("In EsempioByVal2")
            Dim zzz As New Test("Test creato in EsempioByVal2")
            parametro = zzz
        End Sub
        Public Sub EsempioByRef2(ByRef parametro As Test)
            Console.WriteLine("In EsempioByRef2")
            Dim zzz As New Test("Test creato in EsempioByRef2")
            parametro = zzz
        End Sub
        Public Sub EsempioByVal3(ByVal parametro As Test)
            Console.WriteLine(parametro Is tst)
        End Sub
        Public Sub EsempioByRef3(ByRef parametro As Test)
            Console.WriteLine(parametro Is tst)
        End Sub
    End Module
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.