Почему нужно использовать «вне» вместо ref? - PullRequest
4 голосов
/ 29 мая 2010

Я написал несколько блоков кода об объявлении ref -out. Я думаю, что ссылка наиболее полезна. Хорошо. почему я должен использовать. я могу использовать всегда ref каждый раз:

namespace out_ref
{
    class Program
    {
        static void Main(string[] args)
        {
            sinifA sinif = new sinifA();
            int test = 100;
            sinif.MethodA(out test);
            Console.WriteLine(test.ToString());

            sinif.MethodB(ref test);
            Console.WriteLine(test.ToString());
            Console.ReadKey();
        }
    }

    class sinifA
    {

        public void MethodA(out int a)
        {
            a = 200;
        }

        int _b;
        public void MethodB(ref int b)
        {
            _b = b;
            b = 2*b;
        }
    }

}

Ответы [ 5 ]

13 голосов
/ 29 мая 2010

Да, вы можете использовать ref каждый раз, но они имеют разные цели. ref используется, когда параметр является одновременно входом и выходом. out используется, когда параметр является только выходным. Его можно использовать для передачи ввода, но это делает его таким, что пользователю функции не нужно объявлять экземпляр перед использованием функции, потому что вы фактически говорите, что гарантируете, что экземпляр создан. Это особенно полезно в шаблоне TryXXX, когда вы получаете значение из коллекции

6 голосов
/ 29 мая 2010

Если у вас есть параметр с out, к нему не нужно инициализировать его перед передачей методу, который его принимает.

The out keyword causes arguments to be passed by reference. 
This is like the ref keyword, except that ref requires that the variable be initialized 
before it is passed.

От: http://msdn.microsoft.com/en-us/library/ee332485.aspx

3 голосов
/ 29 мая 2010

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

int i;
MyFunc(out i);
.. < use i > ..

без получения ошибки компилятора для неинициализированной переменной.

1 голос
/ 29 мая 2010

ref и out внутренне обрабатываются одинаково, они оба передают переменную по ссылке.

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

С параметрами out это метод, который вы вызываете. Какое бы значение не находилось в переменной, которую вы передаете по ссылке перед вызовом метода, не имеет значения. Компилятор будет жаловаться, если у вызываемого вами метода есть путь выполнения, который не может установить новое значение для своего параметра. Это означает, что любое значение в переменной перед вызовом метода гарантированно будет перезаписано, даже если оно имеет то же значение.

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

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

0 голосов
/ 29 мая 2010

Параметры выхода

В дополнение к передаче значений по ссылке вы также можете указать, что данный параметр является параметром out, используя ключевое слово out, которое используется аналогичным образом.как ключевое слово ref (как модификатор параметра в определении функции и в вызове функции).По сути, это дает вам почти такое же поведение, как и у ссылочного параметра, в котором значение параметра в конце выполнения функции возвращается в переменную, используемую в вызове функции.Однако существуют важные различия:

  1. В то время как использование неназначенной переменной в качестве параметра ref недопустимо, вы можете использовать неназначенную переменную в качестве параметра out
  2. Параметр out долженобрабатывается как функция, которая ее использует, как неназначенное значение.

Это означает, что, хотя при вызове кода допустимо использовать назначенную переменную в качестве параметра out, значение, сохраненное в этой переменной, теряетсякогда функция выполняется.

В качестве примера рассмотрим расширение функции MaxValue (), показанной ранее, которая возвращает максимальное значение массива.Немного измените функцию, чтобы получить индекс элемента с максимальным значением в массиве.Для простоты получите только индекс первого вхождения этого значения, когда имеется несколько элементов с максимальным значением.Для этого добавьте параметр out, изменив функцию следующим образом:

static int MaxValue(int[] intArray, out int maxIndex)

{int maxVal = intArray [0];maxIndex = 0;for (int i = 1; i maxVal) {maxVal = intArray [i];maxIndex = i;}} return maxVal;}

Вы можете использовать эту функцию, как показано здесь:

int[] myArray = {1, 8, 3, 6, 2, 5, 9, 3, 0, 2};

int maxIndex;Console.WriteLine («Максимальное значение в myArray - {0}», MaxValue (myArray, out maxIndex));Console.WriteLine («Первое вхождение этого значения в элементе {0}», maxIndex + 1);

Это приводит к следующему:

Максимальное значение в myArray9

Первое вхождение этого значения в элементе 7

Один был добавлен к значению maxIndex, возвращаемому здесь, когда оноотображается на экране.Это делается для перевода индекса в более читаемую форму, так что первый элемент в массиве называется элементом 1, а не элементом 0.

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