Передача параметров типа значения (руководство по программированию в C#)

Обновлен: Ноябрь 2007

Переменная типа значения содержит данные непосредственно, в противоположность переменной ссылочного типа, которая содержит ссылку на данные. Поэтому передача переменной типа значения методу означает передачу методу копии переменной. Любые изменения параметра, выполняемые внутри метода, не влияют на исходные данные, хранимые в переменной. Если требуется, чтобы вызываемый метод изменял значение параметра, его следует передавать ссылкой с помощью ключевого слова ref или out. Для простоты в следующем примере использовано ключевое слово ref.

Пример

В следующем примере демонстрируется передача параметров типа значения с помощью значения. Переменная n передается с помощью значения в метод SquareIt. Любые изменения, выполняемые внутри метода, не влияют на значение переменной.

class PassingValByVal
{
    static void SquareIt(int x)
    // The parameter x is passed by value.
    // Changes to x will not affect the original value of x.
    {
        x *= x;
        System.Console.WriteLine("The value inside the method: {0}", x);
    }
    static void Main()
    {
        int n = 5;
        System.Console.WriteLine("The value before calling the method: {0}", n);

        SquareIt(n);  // Passing the variable by value.
        System.Console.WriteLine("The value after calling the method: {0}", n);

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}
/* Output:
    The value before calling the method: 5
    The value inside the method: 25
    The value after calling the method: 5
*/

Переменная n, имеющая тип значения, содержит данные, значение 5. При вызове метода SquareIt содержимое переменной n копируется в параметр x, который возводится в квадрат внутри метода. Однако в методе Main значение переменной n остается одинаковым до и после вызова метода SquareIt. Фактически, изменение, выполняемое внутри метода, влияет только на локальную переменную x.

Следующий пример похож на предыдущий за исключением того, что в нем параметр передается с помощью ключевого слова ref. После вызова метода значение параметра изменяется.

class PassingValByRef
{
    static void SquareIt(ref int x)
    // The parameter x is passed by reference.
    // Changes to x will affect the original value of x.
    {
        x *= x;
        System.Console.WriteLine("The value inside the method: {0}", x);
    }
    static void Main()
    {
        int n = 5;
        System.Console.WriteLine("The value before calling the method: {0}", n);

        SquareIt(ref n);  // Passing the variable by reference.
        System.Console.WriteLine("The value after calling the method: {0}", n);

        // Keep the console window open in debug mode.
        System.Console.WriteLine("Press any key to exit.");
        System.Console.ReadKey();
    }
}
/* Output:
    The value before calling the method: 5
    The value inside the method: 25
    The value after calling the method: 25
*/

В этом примере передается не значение переменной n а ссылка на переменную n. Параметр x не является типом int; он является ссылкой на тип int, в данном случае ссылкой на переменную n. Поэтому при возведении в квадрат параметра x внутри метода фактически в квадрат возводится переменная, на которую ссылается параметр x — переменная n.

Распространенным примером замены значений передаваемых параметров является метод Swap, в который передаются две переменные, x и y, и метод меняет местами их содержимое. Параметры необходимо передавать в метод Swap с помощью ссылки. В противном случае внутри метода будут использоваться локальные копии параметров. Ниже приведен пример использования ссылочных параметров в методе Swap.

static void SwapByRef(ref int x, ref int y)
{
    int temp = x;
    x = y;
    y = temp;
}

При вызове этого метода следует использовать ключевое слово ref следующим образом.

static void Main()
{
    int i = 2, j = 3;
    System.Console.WriteLine("i = {0}  j = {1}" , i, j);

    SwapByRef (ref i, ref j);

    System.Console.WriteLine("i = {0}  j = {1}" , i, j);

    // Keep the console window open in debug mode.
    System.Console.WriteLine("Press any key to exit.");
    System.Console.ReadKey();
}
/* Output:
    i = 2  j = 3
    i = 3  j = 2
*/

См. также

Основные понятия

Руководство по программированию в C#

Ссылки

Передача параметров (Руководство по программированию в C#)

Передача параметров ссылочного типа (руководство по программированию в C#)