ref (odwołanie w C#)ref (C# Reference)

ref — Słowo kluczowe wskazuje wartość informującą który jest przekazywany przez odwołanie.The ref keyword indicates a value that is passed by reference. Jest on używany w czterech różnych kontekstach:It is used in four different contexts:

  • W podpisie metody i w wywołaniu metody, aby przekazać argument do metody przez odwołanie.In a method signature and in a method call, to pass an argument to a method by reference. Aby uzyskać więcej informacji, zobacz przekazywaniem argumentu według odwołania.For more information, see Passing an argument by reference.
  • W podpisie metody, aby zwrócić wartości do obiektu wywołującego przez odwołanie.In a method signature, to return a value to the caller by reference. Aby uzyskać więcej informacji, zobacz wartości zwracane odwołanie.For more information, see Reference return values.
  • W treści elementu członkowskiego aby wskazać, że zwracana wartość odwołania są przechowywane lokalnie, jako odwołanie do obiektu wywołującego zamierza zmienić lub ogólnie rzecz biorąc, zmienna lokalna uzyskuje dostęp do innej wartości przez odwołanie.In a member body, to indicate that a reference return value is stored locally as a reference that the caller intends to modify or, in general, a local variable accesses another value by reference. Aby uzyskać więcej informacji, zobacz zmienne lokalne Ref.For more information, see Ref locals.
  • W struct deklaracji, aby zadeklarować ref struct lub ref readonly struct.In a struct declaration to declare a ref struct or a ref readonly struct. Aby uzyskać więcej informacji, zobacz typy struktury ref.For more information, see ref struct types.

Przekazywanie argumentów poprzez odwołaniePassing an argument by reference

Gdy są używane w liście parametrów metody, ref słowo kluczowe wskazuje, że argument jest przekazywany przez odwołanie, nie przez wartość.When used in a method's parameter list, the ref keyword indicates that an argument is passed by reference, not by value. ref — Słowo kluczowe sprawia, że parametr formalny alias dla argumentu, który musi być zmienną.The ref keyword makes the formal parameter an alias for the argument, which must be a variable. Innymi słowy żadnych operacji na parametr składa się od argumentu.In other words, any operation on the parameter is made on the argument. Na przykład jeśli obiekt wywołujący przekazuje wyrażenie lokalnej zmiennej lub wyrażenia dostępu do elementu tablicy, a następnie wywoływana metoda zastępuje obiekt, do którego odwołuje się parametr ref, a następnie obiekt wywołujący użytkownika lokalnego zmienna lub element tablicy teraz odwołuje się do nowego obiektu po Metoda zwraca.For example, if the caller passes a local variable expression or an array element access expression, and the called method replaces the object to which the ref parameter refers, then the caller’s local variable or the array element now refers to the new object when the method returns.

Uwaga

Nie należy mylić koncepcji przekazywanie poprzez odwołanie z pojęciem typy odwołań.Do not confuse the concept of passing by reference with the concept of reference types. Dwoma pojęciami nie są takie same.The two concepts are not the same. Parametr metody mogą być modyfikowane przez ref niezależnie od tego, czy jest typem wartości lub typem referencyjnym.A method parameter can be modified by ref regardless of whether it is a value type or a reference type. Istnieje nie opakowanie typu wartości, gdy jest przekazywany przez odwołanie.There is no boxing of a value type when it is passed by reference.

Aby użyć ref jawnie użyć parametru, zarówno definicję metody, jak i wywoływania metody ref — słowo kluczowe, jak pokazano w poniższym przykładzie.To use a ref parameter, both the method definition and the calling method must explicitly use the ref keyword, as shown in the following example.

void Method(ref int refArgument)
{
    refArgument = refArgument + 44;
}

int number = 1;
Method(ref number);
Console.WriteLine(number);
// Output: 45

Argument, który jest przekazywany do ref lub in parametr musi zostać zainicjowany przed przekazaniem jej.An argument that is passed to a ref or in parameter must be initialized before it is passed. To różni się od się parametrów, w której argumenty nie trzeba jawnie zainicjowane przed przekazaniem ich.This differs from out parameters, whose arguments do not have to be explicitly initialized before they are passed.

Składowa klasy nie może mieć podpisów, które różnią się tylko przez ref, in, lub out.Members of a class can't have signatures that differ only by ref, in, or out. Błąd kompilatora występuje, jeśli jedyną różnicą między dwa elementy członkowskie typu jest, że jedna z nich ma ref parametru, a druga ma out, lub in parametru.A compiler error occurs if the only difference between two members of a type is that one of them has a ref parameter and the other has an out, or in parameter. Na przykład, poniższy kod nie kompilacji.The following code, for example, doesn't compile.

class CS0663_Example
{
    // Compiler error CS0663: "Cannot define overloaded 
    // methods that differ only on ref and out".
    public void SampleMethod(out int i) { }
    public void SampleMethod(ref int i) { }
}

Jednak mogą być przeciążone metody, gdy ma jedną z metod ref, in, lub out parametru, a druga ma wartość parametru, jak pokazano w poniższym przykładzie.However, methods can be overloaded when one method has a ref, in, or out parameter and the other has a value parameter, as shown in the following example.

class RefOverloadExample
{
    public void SampleMethod(int i) { }
    public void SampleMethod(ref int i) { }
}

W innych sytuacjach, które wymagają podpis dopasowania, takich jak ukrywać lub zastępowanie in, ref, i out są dostępne w ramach sygnatury i nie pasują do siebie nawzajem.In other situations that require signature matching, such as hiding or overriding, in, ref, and out are part of the signature and don't match each other.

Właściwości nie są zmienne.Properties are not variables. To metody, a nie można przekazać do ref parametrów.They are methods, and cannot be passed to ref parameters.

Nie można użyć ref, in, i out słowa kluczowe dla następujących rodzajów metod:You can't use the ref, in, and out keywords for the following kinds of methods:

  • Metody asynchroniczne, które można zdefiniować przy użyciu async modyfikator.Async methods, which you define by using the async modifier.
  • Metody iteratora, które obejmują yield return lub yield break instrukcji.Iterator methods, which include a yield return or yield break statement.

Przekazywanie argumentów poprzez odwołanie: PrzykładPassing an argument by reference: An example

Poprzednie przykłady przekazuj typów wartości przez odwołanie.The previous examples pass value types by reference. Można również użyć ref — słowo kluczowe do przekazania odwołania typów przez odwołanie.You can also use the ref keyword to pass reference types by reference. Przekazywanie typu odwołania przez odwołanie pozwala zastąpić obiekt, do którego odwołuje się parametr odwołania w obiekcie wywołującym metodę o nazwie.Passing a reference type by reference enables the called method to replace the object to which the reference parameter refers in the caller. Lokalizacja magazynu obiekt jest przekazywany do metody jako wartość parametru odwołania.The storage location of the object is passed to the method as the value of the reference parameter. Jeśli zmienisz wartość w określonej lokalizacji magazynu parametru (aby wskazywały nowy obiekt), możesz również zmienić lokalizację magazynu, do którego odwołuje się obiekt wywołujący.If you change the value in the storage location of the parameter (to point to a new object), you also change the storage location to which the caller refers. Poniższy przykład przekazuje wystąpienia typu referencyjnego jako ref parametru.The following example passes an instance of a reference type as a ref parameter.

class Product
{
    public Product(string name, int newID)
    {
        ItemName = name;
        ItemID = newID;
    }

    public string ItemName { get; set; }
    public int ItemID { get; set; }
}

private static void ChangeByReference(ref Product itemRef)
{
    // Change the address that is stored in the itemRef parameter.   
    itemRef = new Product("Stapler", 99999);

    // You can change the value of one of the properties of
    // itemRef. The change happens to item in Main as well.
    itemRef.ItemID = 12345;
}

private static void ModifyProductsByReference()
{
    // Declare an instance of Product and display its initial values.
    Product item = new Product("Fasteners", 54321);
    System.Console.WriteLine("Original values in Main.  Name: {0}, ID: {1}\n",
        item.ItemName, item.ItemID);

    // Pass the product instance to ChangeByReference.
    ChangeByReference(ref item);
    System.Console.WriteLine("Back in Main.  Name: {0}, ID: {1}\n",
        item.ItemName, item.ItemID);
}

// This method displays the following output:
// Original values in Main.  Name: Fasteners, ID: 54321
// Back in Main.  Name: Stapler, ID: 12345        

Aby uzyskać więcej informacji dotyczących przekazywania typów referencyjnych według wartości i według odwołania, zobacz przekazywanie parametrów typu odwołanie.For more information about how to pass reference types by value and by reference, see Passing Reference-Type Parameters.

Odwoływanie się do zwracanych wartościReference return values

Wartości zwracane odwołanie (lub zwracanych ref) są wartościami, które metoda zwraca wartość przez odwołanie do obiektu wywołującego.Reference return values (or ref returns) are values that a method returns by reference to the caller. Oznacza to obiekt wywołujący, można zmodyfikować wartości zwracanej przez metodę, a ta zmiana jest odzwierciedlana w stan obiektu, który zawiera metodę.That is, the caller can modify the value returned by a method, and that change is reflected in the state of the object that contains the method.

Odwołanie zwracają wartość jest definiowana za pomocą ref — słowo kluczowe:A reference return value is defined by using the ref keyword:

  • W podpisie metody.In the method signature. Na przykład, następujący podpis metody oznacza, że GetCurrentPrice metoda zwraca Decimal wartość przez odwołanie.For example, the following method signature indicates that the GetCurrentPrice method returns a Decimal value by reference.
public ref decimal GetCurrentPrice()
  • Między return token i zmienna zwracane w return instrukcji w metodzie.Between the return token and the variable returned in a return statement in the method. Na przykład:For example:
return ref DecimalArray[0];

Aby obiekt wywołujący, aby zmodyfikować stan obiektu, musi być przechowywana wartość do zmiennej, która jest jawnie zdefiniowany jako zwrócić odwołanie odwołanie lokalne.In order for the caller to modify the object's state, the reference return value must be stored to a variable that is explicitly defined as a ref local.

Wywoływana metoda również mogą zadeklarować wartość zwracana jako ref readonly zwraca wartość przez odwołanie w celu wymuszenia, aby kod wywołujący nie można zmodyfikować zwracanej wartości.The called method may also declare the return value as ref readonly to return the value by reference, and enforce that the calling code cannot modify the returned value. Kopiowanie zwracanego zwracającej dzięki przechowywaniu wartości w lokalnej uniknąć wywoływania metody ref tylko do odczytu zmiennej.The calling method can avoid copying the returned valued by storing the value in a local ref readonly variable.

Aby uzyskać przykład, zobacz A wartości zwracane ref i przykład zmienne lokalne ref.For an example, see A ref returns and ref locals example.

Zmienne lokalne REFRef locals

Zmienna lokalna ref jest używana do odwoływania się do wartości zwracane wartości przy użyciu return ref.A ref local variable is used to refer to values returned using return ref. Zmienna lokalna ref nie można zainicjować do wartości zwracanej-ref.A ref local variable cannot be initialized to a non-ref return value. Innymi słowy po prawej stronie inicjowania musi być odwołaniem.In other words, the right hand side of the initialization must be a reference. Wszelkie modyfikacje, wartość Zmienna lokalna ref są odzwierciedlane w stan obiektu, którego metoda zwróciła wartość przez odwołanie.Any modifications to the value of the ref local are reflected in the state of the object whose method returned the value by reference.

Zmienna lokalna ref jest definiowane za pomocą ref — słowo kluczowe przed deklaracją zmiennej, a także bezpośrednio przed wywołaniem metody, która zwraca wartość przez odwołanie.You define a ref local by using the ref keyword before the variable declaration, as well as immediately before the call to the method that returns the value by reference.

Na przykład następująca instrukcja definiuje lokalna wartość ref, który jest zwracany przez metodę o nazwie GetEstimatedValue:For example, the following statement defines a ref local value that is returned by a method named GetEstimatedValue:

ref decimal estValue = ref Building.GetEstimatedValue();

Dostępne wartości przez odwołanie, w taki sam sposób.You can access a value by reference in the same way. W niektórych przypadkach uzyskiwanie dostępu do wartości przez odwołanie zwiększa wydajność, unikając operacji kopiowania potencjalnie kosztowne.In some cases, accessing a value by reference increases performance by avoiding a potentially expensive copy operation. Na przykład następująca instrukcja pokazuje, jak jeden można zdefiniować wartości lokalnej ref, służący do odwoływać się do wartości.For example, the following statement shows how one can define a ref local value that is used to reference a value.

ref VeryLargeStruct reflocal = ref veryLargeStruct;

Należy pamiętać, że w obu przykładach ref w obu miejscach, można użyć słowa kluczowego lub kompilator generuje błąd CS8172, "Nie można zainicjować zmiennej przez odwołanie o wartości".Note that in both examples the ref keyword must be used in both places, or the compiler generates error CS8172, "Cannot initialize a by-reference variable with a value."

Począwszy od C# 7.3, zmiennej iteracji foreach instrukcja może być zmienna lokalna ref lub zmiennej lokalnej tylko do odczytu ref.Beginning with C# 7.3, the iteration variable of the foreach statement can be ref local or ref readonly local variable. Aby uzyskać więcej informacji, zobacz Instrukcja foreach artykułu.For more information, see the foreach statement article.

Zmienne lokalne REF tylko do odczytuRef readonly locals

Odwołanie lokalne tylko do odczytu jest używana do odwoływania się do wartości zwracanych przez metodę lub właściwość, która ma ref readonly w jego podpisu i używa return ref.A ref readonly local is used to refer to values returned by the method or property that has ref readonly in its signature and uses return ref. A ref readonly zmiennej łączy właściwości ref zmienna lokalna o readonly zmiennej: jest to alias do magazynu jest przypisany do, a nie można modyfikować.A ref readonly variable combines the properties of a ref local variable with a readonly variable: it is an alias to the storage it's assigned to, and it cannot be modified.

Element wartości zwracane ref i przykład zmienne lokalne refA ref returns and ref locals example

W poniższym przykładzie zdefiniowano Book klasę, która ma dwa String pól Title i Author.The following example defines a Book class that has two String fields, Title and Author. Umożliwia on również definiowanie BookCollection klasa, która zawiera prywatne tablicę Book obiektów.It also defines a BookCollection class that includes a private array of Book objects. Poszczególne książki obiekty są zwracane przez odwołanie, przez wywołanie jego GetBookByTitle metody.Individual book objects are returned by reference by calling its GetBookByTitle method.


public class Book
{
    public string Author;
    public string Title;
}

public class BookCollection
{
    private Book[] books = { new Book { Title = "Call of the Wild, The", Author = "Jack London" },
                        new Book { Title = "Tale of Two Cities, A", Author = "Charles Dickens" }
                       };
    private Book nobook = null;

    public ref Book GetBookByTitle(string title)
    {
        for (int ctr = 0; ctr < books.Length; ctr++)
        {
            if (title == books[ctr].Title)
                return ref books[ctr];
        }
        return ref nobook;
    }

    public void ListBooks()
    {
        foreach (var book in books)
        {
            Console.WriteLine($"{book.Title}, by {book.Author}");
        }
        Console.WriteLine();
    }
}

Gdy obiekt wywołujący przechowuje wartość zwrócona przez obiekt GetBookByTitle zmiany, które sprawia, że obiekt wywołujący na wartość zwracaną metody jako lokalną ref, są odzwierciedlane w BookCollection obiektu, co ilustruje poniższy przykład.When the caller stores the value returned by the GetBookByTitle method as a ref local, changes that the caller makes to the return value are reflected in the BookCollection object, as the following example shows.

var bc = new BookCollection();
bc.ListBooks();

ref var book = ref bc.GetBookByTitle("Call of the Wild, The");
if (book != null)
    book = new Book { Title = "Republic, The", Author = "Plato" };
bc.ListBooks();
// The example displays the following output:
//       Call of the Wild, The, by Jack London
//       Tale of Two Cities, A, by Charles Dickens
//       
//       Republic, The, by Plato
//       Tale of Two Cities, A, by Charles Dickens

Typy struktury REFRef struct types

Dodawanie ref modyfikatora struct deklaracja określa, że wystąpienia tego typu musi znajdować się na stosie.Adding the ref modifier to a struct declaration defines that instances of that type must be stack allocated. Innymi słowy te typy można nigdy nie można tworzyć wystąpień na stosie jest członkiem innej klasy.In other words, instances of these types can never be created on the heap as a member of another class. Główną motywacją do tej funkcji został Span<T> i pokrewne struktury.The primary motivation for this feature was Span<T> and related structures.

Celem zachowywaniu ref struct wpisz zmienną przydzielanych ze stosów wprowadza kilka reguł, które kompilator wymusza dla wszystkich ref struct typów.The goal of keeping a ref struct type as a stack-allocated variable introduces several rules that the compiler enforces for all ref struct types.

  • Nie można polu ref struct.You can't box a ref struct. Nie można przypisać ref struct typ do zmiennej typu object, dynamic, lub dowolny typ interfejsu.You cannot assign a ref struct type to a variable of type object, dynamic, or any interface type.
  • ref struct typy nie mogą implementować interfejsów.ref struct types cannot implement interfaces.
  • Nie można zadeklarować ref struct jako członek pola klasy lub struktury normalny.You can't declare a ref struct as a field member of a class or a normal struct. W tym deklarowanie automatycznie implementowana właściwość, która tworzy polem zapasowym wygenerowanego przez kompilator.This includes declaring an auto-implemented property, which creates a compiler generated backing field.
  • Nie można zadeklarować zmienne lokalne, które są ref struct typów w metodach asynchronicznych.You cannot declare local variables that are ref struct types in async methods. Można zadeklarować je metod synchronicznych, które zwracają Task, Task<TResult> lub Task— takich jak typy.You can declare them in synchronous methods that return Task, Task<TResult> or Task-like types.
  • Nie można zadeklarować ref struct zmiennych lokalnych w iteratorach.You cannot declare ref struct local variables in iterators.
  • Nie można dokonać przechwytu ref struct zmiennych w wyrażeniach lambda lub funkcji lokalnych.You cannot capture ref struct variables in lambda expressions or local functions.

Te ograniczenia, upewnij się, nie używasz przypadkowo ref struct w taki sposób, który można podwyższyć poziom do zarządzanej sterty.These restrictions ensure you don't accidentally use a ref struct in a manner that could promote it to the managed heap.

Można połączyć modyfikatorów, aby zadeklarować struktury jako readonly ref.You can combine modifiers to declare a struct as readonly ref. A readonly ref struct łączy korzyści i ograniczeń dotyczących ref struct i readonly struct deklaracji.A readonly ref struct combines the benefits and restrictions of ref struct and readonly struct declarations.

specyfikacja języka C#C# language specification

Aby uzyskać więcej informacji, zobacz Specyfikacja języka C#.For more information, see the C# Language Specification. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.The language specification is the definitive source for C# syntax and usage.

Zobacz takżeSee also