Пример практического использования "ref"

Я пытаюсь использовать "ref" (передать аргумент по ссылке) в реальном приложении. Я хотел бы иметь простой и в основном осмысленный пример. Все, что я нашел до сих пор, можно легко переделать с добавлением возвращаемого типа методу. Любая идея кого-то? Спасибо!

Ответ 1

Лучший пример, который приходит мне в голову, - это функция для замены двух значений переменных:

static void Swap<T>(ref T el1, ref T el2)
{
    var mem = el1;
    el1 = el2;
    el2 = mem;
}

Использование:

static void Main(string[] args)
{
    string a = "Hello";
    string b = "Hi";

    Swap(ref a, ref b);
    // now a = "Hi" b = "Hello"

    // it works also with array values:
    int[] arr = new[] { 1, 2, 3 };
    Swap(ref arr[0], ref arr[2]);
    // now arr = {3,2,1}
}

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

Ответ 2

Один возможный пример с угловым корпусом: Interlocked.Increment. Не передавая переменную по ссылке, нет никакого способа выполнить приращение атомарно.

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

Ответ 3

Методы TryParse, встроенные в структуру, являются типичными примерами. Они используют out вместо ref, но это одна и та же семантика, это просто, что вызывающему не нужно инициализировать значение. Пример:

int result;
bool isSuccess = int.TryParse("some string", out result);
if (isSuccess)
{
    // use the result here
}

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

Ответ 4

public static void Main(string args[])
{
    int i=0;
    AddSomething(ref i);
    AddSomething(ref i);
    AddSomething(ref i);
    AddSomething(ref i);


    string mystr = "Hello";
    AddSomeText(ref mystr);
    Console.WriteLine(mystr);


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


public static void AddSomeText(ref string str)
{
    str+= " World!";
}


public static void AddSomething(ref int ii)
{
    ii+=1;
}

Ответ 5

Одно из наиболее распространенных мест, которое я вижу в нем, - это методы сохранения некоторых фреймворков.

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

Что касается его НЕОБХОДИМОСТИ, я не могу придумать пример, где это потребуется. Большинство мест просто отлично.

Ответ 6

Я думаю, что хорошим примером будет батут.

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

С уважением, GJ