Поделиться через


ref (справочник по C#)

Ключевое ref слово используется в следующих контекстах:

  • В сигнатуре метода и вызове метода передайте аргумент в метод по ссылке.
class TheClass
{
    public string? willIChange;
}

struct TheStruct
{
    public string willIChange;
}

class TestClassAndStruct
{
    static void ClassTaker(TheClass c)
    {
        c.willIChange = "Changed";
    }

    static void StructTaker(TheStruct s)
    {
        s.willIChange = "Changed";
    }

    public static void Main()
    {
        TheClass testClass = new TheClass();
        TheStruct testStruct = new TheStruct();

        testClass.willIChange = "Not Changed";
        testStruct.willIChange = "Not Changed";

        ClassTaker(testClass);
        StructTaker(testStruct);

        Console.WriteLine("Class field = {0}", testClass.willIChange);
        Console.WriteLine("Struct field = {0}", testStruct.willIChange);
    }
}
/* Output:
    Class field = Changed
    Struct field = Not Changed
*/
  • В сигнатуре метода для возврата значения вызывающему объекту по ссылке. Дополнительные сведения см. в разделе ref return.
int[] xs = new int [] {10, 20, 30, 40 };
ref int found = ref FindFirst(xs, s => s == 30);
found = 0;
Console.WriteLine(string.Join(" ", xs));  // output: 10 20 0 40

ref int FindFirst(int[] numbers, Func<int, bool> predicate)
{
    for (int i = 0; i < numbers.Length; i++)
    {
        if (predicate(numbers[i]))
        {
            return ref numbers[i];
        }
    }
    throw new InvalidOperationException("No element satisfies the given condition.");
}
  • В объявлении локальной переменной для объявления ссылочной переменной.
ref int aliasOfvariable = ref variable;
  • В рамках условного выражения ссылок или оператора назначения ссылок.
void Display(double[] s) => Console.WriteLine(string.Join(" ", s));

double[] arr = { 0.0, 0.0, 0.0 };
Display(arr);

ref double arrayElement = ref arr[0];
arrayElement = 3.0;
Display(arr);

arrayElement = ref arr[arr.Length - 1];
arrayElement = 5.0;
Display(arr);
// Output:
// 0 0 0
// 3 0 0
// 3 0 5
  • В объявлении struct для объявления ref struct. Дополнительные сведения см. в ref статье о типах структур.
public ref struct CustomRef
{
    public bool IsValid;
    public Span<int> Inputs;
    public Span<int> Outputs;
}
public ref struct RefFieldExample
{
    private ref int number;

    public int GetNumber()
    {
        if (System.Runtime.CompilerServices.Unsafe.IsNullRef(ref number))
        {
            throw new InvalidOperationException("The number ref field is not initialized.");
        }

        return number;
    }
}
  • В объявлении универсального типа для указания типов параметров allows ref struct типа.
class SomeClass<T, S>
    where T : allows ref struct
    where S : T
{
    // etc
}