Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

10.6.1.1Параметры по значению

Параметр, объявленный без модификаторов, является параметром по значению. Параметр по значению соответствует локальной переменной, получающей свое начальное значение из соответствующего аргумента, предоставленного во время вызова метода.

Если формальный параметр является параметром по значению, соответствующий аргумент в вызове метода должен быть выражением, неявно преобразуемым (§6.1) в тип формального параметра.

Методу разрешено присваивать новые значения параметру по значению. Такие присваивания влияют только на локальное место хранения, представленное параметром по значению – они не влияют на фактический аргумент, заданный при вызове метода.

10.6.1.2Параметры по ссылке

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

Если формальный параметр является параметром по ссылке, соответствующий аргумент в вызове метода должен состоять из зарезервированного слова ref, за которым следует ссылка_на_переменную (§5.3.3) того же типа, что и формальный параметр. Переменная должна быть определенно назначенной до того, как ее можно будет передать в качестве параметра по ссылке.

Внутри метода параметр по ссылке всегда считается определенно назначенным.

У метода, объявленного как итератор (§10.14), не может быть параметров по ссылке.

Пример:

using System;

class Test { static void Swap(ref int x, ref int y) { int temp = x; x = y; y = temp; }

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

В этом примере производятся следующие выходные данные

i = 2, j = 1

При вызове метода Swap из Main x представляет i, а y представляет j. Таким образом, результатом вызова является обмен значений i и j.

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

class A { string s;

void F(ref string a, ref string b) { s = "One"; a = "Two"; b = "Three"; }

void G() { F(ref s, ref s); } }

вызов F из G передает ссылку на s и для a, и для b. Таким образом, при этом вызове все имена s, a и b ссылаются на одно и то же место хранения, а все три присваивания изменяют поле экземпляра s.

10.6.1.3Выходные параметры

Параметр, объявленный с модификатором out, является выходным параметром. Подобно параметру по ссылке, выходной параметр не создает новое место хранения. Вместо этого выходной параметр представляет то же самое место хранения, что и переменная, заданная в качестве аргумента при вызове метода.

Если формальный параметр является выходным параметром, соответствующий аргумент в вызове метода должен состоять из зарезервированного слова out, за которым следует ссылка_на_переменную (§5.3.3) того же типа, что и формальный параметр. Переменной не требуется быть определенно назначенной, прежде чем ее можно будет передать в качестве выходного параметра, но вслед за вызовом, в котором переменная была передана в качестве выходного параметра, эта переменная считается определенно назначенной.

Внутри метода, точно так же, как и локальная переменная, выходной параметр вначале считается неназначенным, и должен быть определенно назначен до использования его значения.

Каждый выходной параметр метода должен быть определенно назначен до возврата из метода.

Метод, объявленный как частичный (§10.2.7) или как итератор (§10.14), не может иметь выходные параметры.

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

using System;

class Test { static void SplitPath(string path, out string dir, out string name) { int i = path.Length; while (i > 0) { char ch = path[i – 1]; if (ch == '\\' || ch == '/' || ch == ':') break; i--; } dir = path.Substring(0, i); name = path.Substring(i); }

static void Main() { string dir, name; SplitPath("c:\\Windows\\System\\hello.txt", out dir, out name); Console.WriteLine(dir); Console.WriteLine(name); } }

Далее показан вывод для вышеуказанного примера.

c:\Windows\System\ hello.txt

Обратите внимание, что переменным dir и name может быть не сделано присваивание до их передачи в SplitPath, но они считаются определенно назначенными вслед за вызовом.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]