Udostępnij za pośrednictwem


Przekazywanie argumentów według wartości i według odwołania (Visual Basic)

W języku Visual Basic można przekazać argument do procedury według wartości lub przez odwołanie. Jest to nazywane mechanizmem przekazywania i określa, czy procedura może zmodyfikować element programowania będący podstawą argumentu w kodzie wywołującym. Deklaracja procedury określa mechanizm przekazywania dla każdego parametru, określając słowo kluczowe ByVal lub ByRef .

Wyróżnienia

Podczas przekazywania argumentu do procedury należy pamiętać o kilku różnych różnicach, które współdziałają ze sobą:

  • Czy bazowy element programowania jest modyfikowalny, czy niemodyfikowalny

  • Czy sam argument jest modyfikowalny, czy niemodyfikowalny

  • Czy argument jest przekazywany przez wartość czy przez referencję?

  • Czy typ danych argumentu jest typem wartości, czy typem odwołania

Aby uzyskać więcej informacji, zobacz Różnice między modyfikowalnymi i niemodyfikowalnymi argumentami i różnicami między przekazywaniem argumentu według wartości i przez odwołanie.

Wybór mechanizmu przekazywania

Należy dokładnie wybrać mechanizm przekazywania dla każdego argumentu.

  • Ochrona. Wybierając między dwoma mechanizmami przekazywania, najważniejszym kryterium jest narażenie zmiennych wywołujących na zmianę. Zaletą przekazania argumentu ByRef jest to, że procedura może zwrócić wartość do kodu wywołującego za pomocą tego argumentu. Zaletą przekazywania argumentu ByVal jest to, że chroni zmienną przed zmianą przez procedurę.

  • Wydajność. Mimo że mechanizm przekazywania może mieć wpływ na wydajność kodu, różnica jest zwykle nieznaczna. Jednym z wyjątków jest typ wartości przekazywany jako ByVal. W tym przypadku program Visual Basic kopiuje całą zawartość danych argumentu. Dlatego w przypadku dużych typów wartości, takich jak struktura, bardziej efektywne może być jej przekazanie ByRef.

    W przypadku typów referencyjnych tylko wskaźnik do danych jest kopiowany (cztery bajty na platformach 32-bitowych, osiem bajtów na platformach 64-bitowych). W związku z tym można przekazać argumenty typu String lub Object według wartości bez szkody dla wydajności.

Określanie mechanizmu przekazywania

Deklaracja procedury określa mechanizm przekazywania dla każdego parametru. Kod wywołujący nie może zastąpić ByVal mechanizmu.

Jeśli parametr jest zadeklarowany za pomocą ByRef, kod wywołujący może wymusić działanie mechanizmu ByVal przez umieszczenie nazwy argumentu w nawiasach podczas wywołania. Aby uzyskać więcej informacji, zobacz How to: Force an Argument to Be Passed by Value (Instrukcje: wymuszanie przekazania argumentu według wartości).

Wartością domyślną w języku Visual Basic jest przekazywanie argumentów według wartości.

Kiedy przekazać argument według wartości

  • Jeśli element kodu wywołującego będący podstawą argumentu jest elementem niemodyfikowalnym, zadeklaruj odpowiedni parametr ByVal. Żaden kod nie może zmienić wartości elementu niemodyfikowalnego.

  • Jeśli element bazowy jest modyfikowalny, ale nie chcesz, aby procedura mogła zmienić jego wartość, zadeklaruj parametr ByVal. Tylko kod wywołujący może zmienić wartość modyfikowalnego elementu przekazanego przez wartość.

Kiedy przekazać argument przez referencję

  • Jeśli procedura ma rzeczywistą potrzebę zmiany podstawowego elementu w kodzie wywołującym, zadeklaruj odpowiedni parametr ByRef.

  • Jeśli poprawne wykonanie kodu zależy od procedury zmiany podstawowego elementu w kodzie wywołującym, zadeklaruj parametr ByRef. Jeśli przekazujesz go według wartości lub jeśli kod wywołujący zastępuje ByRef mechanizm przekazywania przez dołączenie argumentu w nawiasach, wywołanie procedury może spowodować nieoczekiwane wyniki.

Przykład

Opis

Poniższy przykład ilustruje, kiedy przekazać argumenty według wartości i kiedy przekazać je według odwołania. Procedura Calculate ma zarówno parametr ByVal, jak i ByRef. Biorąc pod uwagę stopę procentową, ratei sumę pieniędzy, debtzadaniem procedury jest obliczenie nowej wartości debt , która jest wynikiem zastosowania stopy procentowej do pierwotnej wartości debt. Ponieważ debt jest parametremByRef, nowa suma jest odzwierciedlana w wartości argumentu w kodzie wywołującym, który odpowiada .debt Parametr rate jest parametrem ByVal , ponieważ Calculate nie powinien zmieniać jego wartości.

Kod

Module Module1

    Sub Main()
        ' Two interest rates are declared, one a constant and one a 
        ' variable.
        Const highRate As Double = 12.5
        Dim lowRate = highRate * 0.6

        Dim initialDebt = 4999.99
        ' Make a copy of the original value of the debt.
        Dim debtWithInterest = initialDebt

        ' Calculate the total debt with the high interest rate applied.
        ' Argument highRate is a constant, which is appropriate for a 
        ' ByVal parameter. Argument debtWithInterest must be a variable
        ' because the procedure will change its value to the calculated
        ' total with interest applied.
        Calculate(highRate, debtWithInterest)
        ' Format the result to represent currency, and display it.
        Dim debtString = Format(debtWithInterest, "C")
        Console.WriteLine("What I owe with high interest: " & debtString)

        ' Repeat the process with lowRate. Argument lowRate is not a 
        ' constant, but the ByVal parameter protects it from accidental
        ' or intentional change by the procedure. 

        ' Set debtWithInterest back to the original value.
        debtWithInterest = initialDebt
        Calculate(lowRate, debtWithInterest)
        debtString = Format(debtWithInterest, "C")
        Console.WriteLine("What I owe with low interest:  " & debtString)
    End Sub

    ' Parameter rate is a ByVal parameter because the procedure should
    ' not change the value of the corresponding argument in the 
    ' calling code. 

    ' The calculated value of the debt parameter, however, should be
    ' reflected in the value of the corresponding argument in the 
    ' calling code. Therefore, it must be declared ByRef. 
    Sub Calculate(ByVal rate As Double, ByRef debt As Double)
        debt = debt + (debt * rate / 100)
    End Sub

End Module

Zobacz także