ref (C# Başvurusu)ref (C# Reference)

Anahtar ref kelime, başvuru yla geçirilen bir değeri gösterir.The ref keyword indicates a value that is passed by reference. Dört farklı bağlamda kullanılır:It is used in four different contexts:

  • Bir yöntem imza ve bir yöntem arama, başvuru ile bir yönteme bir argüman geçmek için.In a method signature and in a method call, to pass an argument to a method by reference. Daha fazla bilgi için bkz.For more information, see Passing an argument by reference.
  • Bir yöntem imzasında, başvuru ile arayana bir değer döndürmek için.In a method signature, to return a value to the caller by reference. Daha fazla bilgi için Bkz. Başvuru iade değerleri.For more information, see Reference return values.
  • Bir üye gövdesinde, bir referans dönüş değerinin, arayanın değiştirmek istediği bir başvuru olarak yerel olarak depolandığını veya genel olarak yerel bir değişkenin başvuru yla başka bir değere eriştiğini belirtmek için.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. Daha fazla bilgi için Ref yerel bilgilerinebakın.For more information, see Ref locals.
  • Bir struct veya bir ref struct readonly ref structbeyanda .In a struct declaration to declare a ref struct or a readonly ref struct. Daha fazla bilgi için ref struct türlerinebakın.For more information, see ref struct types.

Bir bağımsız değişkeni başvuruyla geçirmePassing an argument by reference

Bir yöntemin ref parametre listesinde kullanıldığında, anahtar kelime bir bağımsız değişkenin değere göre değil, başvuru yla geçirildiğini gösterir.When used in a method's parameter list, the ref keyword indicates that an argument is passed by reference, not by value. Anahtar ref kelime, resmi parametreyi bağımsız değişken için bir diğer ad yapar ve bu da değişken olmalıdır.The ref keyword makes the formal parameter an alias for the argument, which must be a variable. Başka bir deyişle, parametre üzerinde herhangi bir işlem bağımsız değişken üzerinde yapılır.In other words, any operation on the parameter is made on the argument. Örneğin, arayan yerel bir değişken ifadesini veya dizi öğesi erişim ifadesini geçerse ve çağrılan yöntem ref parametrenin başvurulduğu nesnenin yerini alırsa, arayanın yerel değişkeni veya dizi öğesi yöntem döndüğünde şimdi yeni nesneye başvurur.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.

Not

Referans la geçme kavramını başvuru türleri kavramıyla karıştırmayın.Do not confuse the concept of passing by reference with the concept of reference types. İki kavram aynı değildir.The two concepts are not the same. Yöntem parametresi, değer ref türü veya başvuru türü olup olmadığına bakılmaksızın değiştirilebilir.A method parameter can be modified by ref regardless of whether it is a value type or a reference type. Başvuru yla geçirildiğinde değer türünün kutulamayoktur.There is no boxing of a value type when it is passed by reference.

Bir ref parametre kullanmak için, hem yöntem tanımı hem de ref arama yöntemi, aşağıdaki örnekte gösterildiği gibi anahtar kelimeyi açıkça kullanmalıdır.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

Bir ref veya in parametreye geçirilen bir bağımsız değişken geçirilmeden önce başharfe atılmalıdır.An argument that is passed to a ref or in parameter must be initialized before it is passed. Bu, bağımsız değişkenleri geçirilmeden önce açıkça başlatılması gerekmeyen dış parametrelerden farklıdır.This differs from out parameters, whose arguments do not have to be explicitly initialized before they are passed.

Bir sınıfın üyeleri yalnızca ref, inveya out.Members of a class can't have signatures that differ only by ref, in, or out. Bir türiki üye arasındaki tek fark, birinin ref parametresi, diğerinin ise bir outparametresi in veya parametresi olması ysa derleyici hatası oluşur.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. Örneğin, aşağıdaki kod derlenmiyor.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) { }
}

Ancak, yöntemlerden biri ref, , inparametresi out ve diğer bir değer parametresi varsa, aşağıdaki örnekte gösterildiği gibi aşırı yüklenebilir.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) { }
}

Gizleme veya geçersiz kılma in refgibi imza eşleştirmegerektiren ve imzanın bir parçası olan ve out birbiriyle eşleşmeyen diğer durumlarda.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.

Özellikler değişken değildir.Properties are not variables. Bunlar yöntemdir ve parametrelere ref geçirilemez.They are methods, and cannot be passed to ref parameters.

Aşağıdaki yöntem türleri refiçin in, out ve anahtar kelimeleri kullanamazsınız:You can't use the ref, in, and out keywords for the following kinds of methods:

  • Async değiştirici kullanarak tanımladığınız async yöntemleri.Async methods, which you define by using the async modifier.
  • Verim getirisi veya yield break deyimi içeren yineleyici yöntemleri.Iterator methods, which include a yield return or yield break statement.

Buna ek olarak, uzantı yöntemleri aşağıdaki kısıtlamalara sahiptir:In addition, extension methods have the following restrictions:

  • Anahtar out kelime, bir uzantı yönteminin ilk bağımsız değişkeninde kullanılamaz.The out keyword cannot be used on the first argument of an extension method.
  • Anahtar ref kelime, bağımsız değişken bir yapı olmadığında veya yapı olarak sınırlandırılmamış genel bir tür olduğunda, uzantı yönteminin ilk bağımsız değişkeninde kullanılamaz.The ref keyword cannot be used on the first argument of an extension method when the argument is not a struct, or a generic type not constrained to be a struct.
  • İlk in bağımsız değişken bir yapı olmadığı sürece anahtar sözcük kullanılamaz.The in keyword cannot be used unless the first argument is a struct. Anahtar in kelime, yapı olarak sınırlandırılsa bile, herhangi bir genel türde kullanılamaz.The in keyword cannot be used on any generic type, even when constrained to be a struct.

Bir bağımsız değişkeni başvuruyla geçirme: Bir örnekPassing an argument by reference: An example

Önceki örnekler referansa göre değer türlerini geçer.The previous examples pass value types by reference. Referans türlerini ref başvuruya göre geçirmek için anahtar sözcüğü de kullanabilirsiniz.You can also use the ref keyword to pass reference types by reference. Başvuru türünü referansla geçmek, başvuru parametresinin arayanda başvururolduğu nesneyi değiştirmek için çağrılan yöntemin değiştirilmesine olanak tanır.Passing a reference type by reference enables the called method to replace the object to which the reference parameter refers in the caller. Nesnenin depolama konumu, başvuru parametresi değeri olarak yönteme geçirilir.The storage location of the object is passed to the method as the value of the reference parameter. Parametrenin depolama konumundaki değeri değiştirirseniz (yeni bir nesneye işaret etmek için), arayanın başvurulması gereken depolama konumunu da değiştirirsiniz.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. Aşağıdaki örnek, ref parametre olarak bir başvuru türü örneğini geçer.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        

Referans türlerinin değere ve başvuruya göre nasıl geçirilen hakkında daha fazla bilgi için Bkz.For more information about how to pass reference types by value and by reference, see Passing Reference-Type Parameters.

Başvuru dönüş değerleriReference return values

Başvuru iade değerleri (veya ref returns) bir yöntemin arayana başvuruyla döndürdettiği değerlerdir.Reference return values (or ref returns) are values that a method returns by reference to the caller. Diğer bir deyişle, arayan bir yöntem tarafından döndürülen değeri değiştirebilir ve bu değişiklik yöntemi içeren nesnenin durumuna yansıtılır.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.

Bir referans iade değeri anahtar ref sözcüğü kullanılarak tanımlanır:A reference return value is defined by using the ref keyword:

  • Yöntem imzasında.In the method signature. Örneğin, aşağıdaki yöntem imzası yöntemin GetCurrentPrice başvuru Decimal tarafından bir değer döndürür gösterir.For example, the following method signature indicates that the GetCurrentPrice method returns a Decimal value by reference.
public ref decimal GetCurrentPrice()
  • Belirteç return ve değişken arasında return yöntemde bir ifade döndürülür.Between the return token and the variable returned in a return statement in the method. Örneğin:For example:
return ref DecimalArray[0];

Arayanın nesnenin durumunu değiştirebilmesi için, başvuru iade değerinin ref yerelolarak açıkça tanımlanan bir değişkene depolanmış olması gerekir.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.

Çağrılan yöntem, iade değerini başvuru ref readonly yla değeri döndürecek şekilde bildirebilir ve arama kodunun döndürülen değeri değiştiremeyeceğini zorlayabilir.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. Arama yöntemi, değeri yerel bir ref readonly değişkeninde depolayarak döndürülen değeri kopyalamaktan kaçınabilir.The calling method can avoid copying the returned valued by storing the value in a local ref readonly variable.

Örneğin, bkz.For an example, see A ref returns and ref locals example.

Ref yerlileriRef locals

Ref yerel değişkeni kullanılarak return refdöndürülen değerlere başvurmak için kullanılır.A ref local variable is used to refer to values returned using return ref. Bir ref yerel değişkeni, ref olmayan bir geri dönüş değerine başolarak başlılamaz.A ref local variable cannot be initialized to a non-ref return value. Başka bir deyişle, başlaştırmanın sağ tarafı bir başvuru olmalıdır.In other words, the right-hand side of the initialization must be a reference. Ref yerel değeri herhangi bir değişiklik yöntemi referans tarafından değeri döndürülen nesnenin durumuna yansıtılır.Any modifications to the value of the ref local are reflected in the state of the object whose method returned the value by reference.

Değişken bildiriminden ref önce anahtar sözcüğü kullanarak ve başvuru değeri döndüren yönteme çağrıdan hemen önce bir ref yerel tanımlarsınız.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.

Örneğin, aşağıdaki deyim, adlı GetEstimatedValuebir yöntemle döndürülen bir ref yerel değerini tanımlar:For example, the following statement defines a ref local value that is returned by a method named GetEstimatedValue:

ref decimal estValue = ref Building.GetEstimatedValue();

Bir değere aynı şekilde başvuru yla erişebilirsiniz.You can access a value by reference in the same way. Bazı durumlarda, bir değere referans la erişmek, pahalı olabilecek bir kopyalama işleminden kaçınarak performansı artırır.In some cases, accessing a value by reference increases performance by avoiding a potentially expensive copy operation. Örneğin, aşağıdaki deyim, bir değere başvurmak için kullanılan bir ref yerel değerini nasıl tanımlayabileceğini gösterir.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;

Her iki ref örnekte de anahtar kelime her iki yerde de kullanılmalıdır veya derleyici CS8172 hatası oluşturur, "Bir değerle bir referans değişkeni başharflenemez."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."

C# 7.3 ile başlayarak, ifadenin foreach yineleme değişkeni ref lokal veya ref readonlyonly local değişken olabilir.Beginning with C# 7.3, the iteration variable of the foreach statement can be ref local or ref readonly local variable. Daha fazla bilgi için foreach deyimi makalesine bakın.For more information, see the foreach statement article.

Ayrıca C# 7.3 ile başlayarak, ref atama işleciile bir ref yerel veya ref readonlyonly local değişken yeniden atayabilirsiniz.Also beginning with C# 7.3, you can reassign a ref local or ref readonly local variable with the ref assignment operator.

Ref sadece yerlileri okuyorRef readonly locals

Bir ref readonly yerel imzası ve kullandığı ref readonly return refyöntem veya özellik tarafından döndürülen değerleri başvurmak için kullanılır.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. Bir ref readonly değişken yerel değişkenin ref özelliklerini bir readonly değişkenle birleştirir: atandığı depolamanın diğer adıdır ve değiştirilemez.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.

Bir ref döner ve ref locals örneğiA ref returns and ref locals example

Aşağıdaki örnekte iki Book String alanı olan bir Title Authorsınıf tanımlanır ve .The following example defines a Book class that has two String fields, Title and Author. Ayrıca, özel BookCollection bir Book nesne dizisi içeren bir sınıf tanımlar.It also defines a BookCollection class that includes a private array of Book objects. Tek tek kitap nesneleri, GetBookByTitle yöntemini çağırarak referans la döndürülür.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();
    }
}

Arayan GetBookByTitle yöntem tarafından döndürülen değeri bir ref yerel olarak depoladığında, aşağıdaki örnekte görüldüğü BookCollection gibi, arayanın return value'a yaptığı değişiklikler nesneye yansıtılır.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

Ref yapı tipleriRef struct types

struct Bir bildirime ref değiştirici nin eklenmesi, bu tür örneklerin yığın ayrılması gerektiğini tanımlar.Adding the ref modifier to a struct declaration defines that instances of that type must be stack allocated. Başka bir deyişle, bu tür örnekler başka bir sınıfın bir üyesi olarak yığın üzerinde oluşturulamaz.In other words, instances of these types can never be created on the heap as a member of another class. Bu özelliğin temel Span<T> motivasyonu ve ilgili yapılardır.The primary motivation for this feature was Span<T> and related structures.

Bir ref struct türü yığın ayrılmış değişken olarak tutma hedefi, derleyicinin tüm ref struct türler için uyguladığı çeşitli kurallar sunar.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.

  • Bir ref structşey için boks yapamazsınız.You can't box a ref struct. Bir tür, ref struct tür object, dynamicveya herhangi bir arabirim türü değişkenine atayamazsınız.You cannot assign a ref struct type to a variable of type object, dynamic, or any interface type.
  • ref structtürler arabirimleri uygulayamaz.ref struct types cannot implement interfaces.
  • Bir ref struct sınıfın alan üyesi veya normal bir yapı olarak beyan edemezsiniz.You can't declare a ref struct as a field member of a class or a normal struct. Bu, derleyici tarafından oluşturulan bir destek alanı oluşturan otomatik olarak uygulanan bir özelliği bildirmeyi içerir.This includes declaring an auto-implemented property, which creates a compiler-generated backing field.
  • Async yöntemleri ref struct türleri yerel değişkenler bildiremezsiniz.You cannot declare local variables that are ref struct types in async methods. Bunları, döndüren Task Task<TResult>eşzamanlı yöntemlerle veya Task-benzeri türlerde bildirebilirsiniz.You can declare them in synchronous methods that return Task, Task<TResult>, or Task-like types.
  • Yineleyicilerde ref struct yerel değişkenleri bildiremezsiniz.You cannot declare ref struct local variables in iterators.
  • Lambda ref struct ifadelerinde veya yerel işlevlerde değişkenleri yakalayamamazsınız.You cannot capture ref struct variables in lambda expressions or local functions.

Bu kısıtlamalar, yanlışlıkla yönetilen yığına tanıtacak şekilde kullanmamanızı ref struct sağlar.These restrictions ensure you don't accidentally use a ref struct in a manner that could promote it to the managed heap.

Bir yapıyı " olarak readonly refbildirmek için değiştiricileri birleştirebilirsiniz.You can combine modifiers to declare a struct as readonly ref. A readonly ref struct yararları ve kısıtlamaları ref struct ve readonly struct bildirimleri birleştirir.A readonly ref struct combines the benefits and restrictions of ref struct and readonly struct declarations.

C# dili belirtimiC# language specification

Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi.For more information, see the C# Language Specification. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.The language specification is the definitive source for C# syntax and usage.

Ayrıca bkz.See also