Я пытаюсь использовать "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