Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Заочники_АСОИ / Лекции / 01 Классы / Объекты и типы.docx
Скачиваний:
20
Добавлен:
29.02.2016
Размер:
97.14 Кб
Скачать

Передача параметров в методы

В общем случае параметры могут передаваться методу 'либо по значению, либо по ссылке. Когда переменная передается по ссылке, вызываемый метод получает саму пере­менную, поэтому любые изменения, которым она подвергнется внутри метода, останутся в силе после его завершения. Но если переменная передается по значению, вызываемый метод получает копию этой переменной, а это значит, что все изменения в ней по завер­шении метода будут утеряны. Для сложных типов данных передача по ссылке более эффек­тивна из-за большого объема данных, который приходится копировать при передаче по значению.

Если не указано обратное, то в С# все параметры передаются по значению. Однако нуж­но быть осторожным с пониманием этого в отношении ссылочных типов. Поскольку пе­ременная ссылочного типа содержит лишь ссылку на объект, то именно ссылка будет ско­пирована при передаче параметра, а не сам объект.. То есть изменения, произведенные в самом объекте, сохранятся. В отличие от этого, переменные типа значений действительно содержат данные, поэтому в метод передается копия самих данных. Например, int пере­дается в метод по значению, и любые изменения, которые сделает метод в этом int, не из­менят значения исходного объекта. В противоположность этому, если в метод передается массив или любой другой ссылочный тип, такой как класс, и метод использует эту ссылку для изменения значения в массиве, то это новое значение будет отражено в исходном объ­екте массива.

Сказанное выше иллюстрируется в следующем примере, ParameterTest.cs.

ParameterTest.cs

using System;

namespace Wrox

{

class ParameterTest

{

static void SomeFunction(int[] ints, int i)

{

ints[0] = 100;

i = 100;

}

public static int Main()

{

int i = 0;

int[] ints = { 0, 1, 2, 4, 8 };

// Display the original values

Console.WriteLine("i = " + i);

Console.WriteLine("ints[0] = " + ints[0]);

Console.WriteLine("Calling SomeFunction...");

// After this method returns, ints will be changed,

// but i will not

SomeFunction(ints, i);

Console.WriteLine("i = " + i);

Console.WriteLine("ints[0] = " + ints[0]);

return 0;

}

}

}

Ниже показан вывод этой программы:

ParameterTest.exe i = 0

ints[0) = 0

Вызов SomeFunction...

i = 0

ints[0] = 100

Обратите внимание, что значение i осталось неизменным, но измененные значения в ints также изменились в исходном массиве.

Поведение строк также отличается. Дело в том, что строки являются неизменными (из­менение значения строки то приводит к созданию совершенно новой строки), поэтому строки не демонстрируют поведение, характерное для ссылочных типов. Любые измене­ния, проведенные в строке внутри метода, не влияют на исходную строку. Этот момент более подробно обсуждается в разделе 6.9.

Параметры ref

Как уже упоминалось, по умолчанию параметры передаются по значению. Тем не менее, можно принудительно передавать значения по ссылке, для чего используется ключевое слово ref. Если параметр передается в метод, и входной аргумент этого метода снабжен префиксом ref, то любые изменения этой переменной, которые сделает метод, отразятся на исходном объекте:

static void SomeFunction (int [ ] ints, ref int i)

{

ints[0] = 100;

i = 100;

// изменение i сохранится после завершения SomeFunction ()

}

Ключевое слово ref также должно быть указано при вызове метода:

SomeFunction(ints, ref i);

И, наконец, также важно понимать, что С# распространяет требование инициализации на параметры, переданные методу. Любая переменная должна быть инициализирована прежде, чем она будет передана в метод, независимо от того, передается она по значению или ссылке.

Соседние файлы в папке 01 Классы