ref (C# Başvurusu)
anahtar ref sözcüğü, bir değerin başvuruyla geçir olduğunu gösterir. Dört farklı bağlamda kullanılır:
- Bir yöntem imzada ve yöntem çağrısında, bir bağımsız değişkeni başvuruya göre bir yönteme iletir. Daha fazla bilgi için bkz. Başvuruya göre bağımsız değişken geçirme.
- Bir yöntem imzada, başvuruya göre çağırana bir değer döndürülür. Daha fazla bilgi için bkz. Başvuru dönüş değerleri.
- Bir üye gövdesinde, bir başvuru dönüş değerinin, çağıranın değiştirmeyi amacına uygun bir başvuru olarak yerel olarak depolandığına işaret etmek için. Veya yerel bir değişkenin başvuruya göre başka bir değere erişeni belirtmek için. Daha fazla bilgi için bkz. Ref locals.
- Bir
structbildiriminde, veya bildirimiref structiçinreadonly ref struct. Daha fazla bilgi için Yapıreftürleri makalesinde yapı bölümüne bakın.
Başvuruya göre bağımsız değişken geçirme
Yöntemin parametre listesinde kullanıldığında anahtar sözcüğü, bir bağımsız değişkenin değere göre değil ref başvuruyla geçir olduğunu gösterir. anahtar ref sözcüğü, biçimsel parametreyi değişken olması gereken bağımsız değişken için diğer ad yapar. Başka bir deyişle, parametresinde yapılan herhangi bir işlem bağımsız değişkende yapılır.
Örneğin, çağıranın bir yerel değişken ifadesi veya bir dizi öğesi erişim ifadesi iletir. Çağrılan yöntem daha sonra başvuru parametresinin başvurduğu nesneyi değiştirebilir. Bu durumda, yöntem döndür olduğunda çağıranın yerel değişkeni veya dizi öğesi yeni nesneye başvurur.
Not
Başvuruya göre geçirme kavramını başvuru türleri kavramıyla karıştırmayın. İki kavram aynı değildir. Yöntem parametresi, değer türü ref veya başvuru türüne bakılmaksızın değiştirilebilir. Başvuruyla geçiriken değer türünün kutulama değeri yoktur.
Bir parametre kullanmak için, aşağıdaki örnekte gösterildiği gibi hem yöntem tanımı hem de çağıran yöntemin anahtar ref ref sözcüğünü açıkça kullanması gerekir. (Ancak, bir COM çağrısı yaparken ref çağıran yöntemi atlar.)
void Method(ref int refArgument)
{
refArgument = refArgument + 44;
}
int number = 1;
Method(ref number);
Console.WriteLine(number);
// Output: 45
Bir veya parametresine geçirilen ref bağımsız in değişkenin geçirimeden önce başlatılması gerekir. Bu gereksinim, bağımsız değişkenleri geçirimeden önce açıkça başlatılması gerek olmayan out parametrelerinden farklıdır.
Bir sınıfın üyeleri yalnızca , veya ile farklı ref imzalara in sahip out değildir. Bir türün iki üyesi arasındaki tek fark, birinin parametresi, diğeri ise bir veya parametresine sahipse derleyici ref out hatası in oluşur. Örneğin aşağıdaki kod derlenmiş değil.
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 , veya parametresine sahipken diğeri, aşağıdaki örnekte gösterildiği gibi değere göre geçirilen bir parametreye sahip olduğunda ref in aşırı out yüklenebilirsiniz.
class RefOverloadExample
{
public void SampleMethod(int i) { }
public void SampleMethod(ref int i) { }
}
, ve gizleme veya geçersiz kılma gibi imza eşleştirme gerektiren diğer durumlarda, ve imzanın bir parçası olur in ref ve out eşleşmez.
Özellikler değişken değildir. Bunlar yöntemdir ve parametrelere ref geçirile değildir.
Aşağıdaki yöntem türleri için ref in , ve anahtar out sözcüklerini kullanasınız:
- Zaman uyumsuz değiştiriciyi kullanarak tanımladığınız zaman uyumsuz yöntemler.
- Bir veya daha fazla deyimi içeren yield return
yield breakyöntemleri.
uzantı yöntemlerinin de şu anahtar sözcüklerin kullanımıyla ilgili kısıtlamaları vardır:
- anahtar
outsözcüğü bir uzantı yönteminin ilk bağımsız değişkende kullanılamaz. - Bağımsız değişken bir yapı veya bir yapı olacak şekilde kısıtlanmış genel bir tür değilken anahtar sözcüğü bir uzantı yönteminin ilk bağımsız
refdeğişkende kullanılamaz. - İlk
inbağımsız değişken bir yapı olmadığı sürece anahtar sözcüğü kullanılamaz. Anahtarinsözcüğü, yapı olarak kısıtlanmış olsa bile hiçbir genel türde kullanılamaz.
Başvuruya göre bağımsız değişken geçirme: Örnek
Önceki örnekler değer türlerini başvuruya göre iletir. Başvuru türlerini başvuruya göre ref geçmek için anahtar sözcüğünü de kullanabilirsiniz. Başvuruya göre başvuru türü geçirme, çağrılan yöntemin başvuru parametresinin çağıranda başvurduğu nesneyi değiştirmesini sağlar. Nesnenin depolama konumu, başvuru parametresinin değeri olarak yöntemine geçirildi. Parametrenin depolama konumu değerini değiştirir (yeni bir nesneye işaret etmek için), çağıranın başvurduğu depolama konumunu da değiştirirsiniz. Aşağıdaki örnek, başvuru türünün bir örneğini parametre olarak ref iletir.
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
Başvuru türlerini değere ve başvuruya göre geçirme hakkında daha fazla bilgi için bkz. Reference-Type Geçirme.
Başvuru dönüş değerleri
Başvuru dönüş değerleri (veya başvuru dönüşleri), bir yöntemin çağıranın başvurusuyla döndüren değerlerdir. Yani, çağıran bir yöntem tarafından döndürülen değeri değiştirebilir ve bu değişiklik çağırma yönteminde nesnenin durumuna yansıtıldı.
Başvuru dönüş değeri, anahtar sözcüğü kullanılarak ref tanımlanır:
- Yöntem imzasıyla. Örneğin, aşağıdaki yöntem imzası yöntemin
GetCurrentPricebaşvuruya göre bir Decimal değer döndürerek olduğunu gösterir.
public ref decimal GetCurrentPrice()
returnbelirteci ile yönteminde birreturndeyiminde döndürülen değişken arasında. Örnek:
return ref DecimalArray[0];
Çağıranın nesnenin durumunu değiştirmesi için başvuru dönüş değerinin açıkça başvuru yerel değeri olarak tanımlanan bir değişkende depolanmış olması gerekir.
Burada, hem yöntem imzasını hem de yöntem gövdeyi gösteren daha eksiksiz bir başvuru dönüş örneği ve ardından yer velanmıştır.
public static ref int Find(int[,] matrix, Func<int, bool> predicate)
{
for (int i = 0; i < matrix.GetLength(0); i++)
for (int j = 0; j < matrix.GetLength(1); j++)
if (predicate(matrix[i, j]))
return ref matrix[i, j];
throw new InvalidOperationException("Not found");
}
Çağrılan yöntem ayrıca, başvuruya göre değerin döndürülerek dönüş değerini olarak bildirerek, çağrı kodunun döndürülen değeri ref readonly değiştireye zorlaması da olabilir. Çağıran yöntem, değeri salt okunur yerel bir değişkende depolayarak döndürülen değeri kopyalamayı önleyebilirsiniz.
Bir örnek için bkz. Başvuru dönüşleri ve başvuru yerelleri örneği.
Başvuru yerelleri
kullanılarak döndürülen değerlere başvurmak için başvuru yerel değişkeni return ref kullanılır. Başvuru olmayan bir dönüş değerine başvuru yerel değişkeni başlatılamıyor. Başka bir deyişle, başlatmanın sağ tarafı bir başvuru olması gerekir. Başvuru yerel değerinin tüm değişiklikleri, yöntemi başvuruya göre değeri döndürülen nesnenin durumuna yansıtıldı.
İki yerde anahtar sözcüğünü kullanarak yerel ref başvuru tanımlamanız gerekir:
- Değişken bildiriminin öncesinde.
- Başvuruya göre değeri döndüren yöntem çağrısının hemen öncesinde.
Örneğin, aşağıdaki deyim adlı bir yöntem tarafından döndürülen başvuru yerel değerini GetEstimatedValue tanımlar:
ref decimal estValue = ref Building.GetEstimatedValue();
Bir değere başvuruyla aynı şekilde erişin. Bazı durumlarda, bir değere başvuruyla erişmek, pahalı olabilecek bir kopyalama işlemi önerek performansı artırır. Örneğin, aşağıdaki deyim bir değere başvuru yapmak için kullanılan bir başvuru yerel değişkeninin nasıl tanımlandırılı olduğunu gösterir.
ref VeryLargeStruct reflocal = ref veryLargeStruct;
Her iki örnekte de anahtar sözcüğü her iki yerde de kullanılmalıdır veya derleyici ref CS8172 hatasını oluşturur: "Bir değerle bir by-reference değişkeni başlatılamıyor."
C# 7.3'den itibaren deyiminin yineleme değişkeni ref yerel veya foreach ref salt okunur yerel değişken olabilir. Daha fazla bilgi için foreach deyimi makalesine bakın.
Ayrıca C# 7.3'den itibaren, başvuru atama işleciyle bir ref yerel veya ref salt okunur yerel değişkeni yeniden ayaz edebilirsiniz.
Salt okunur yerel başvurular
Bir başvuru salt okunur yerel, imzasını ve kullanan bir yöntem veya özellik tarafından döndürülen değerlere ref readonly başvurmak için return ref kullanılır. Değişken, yerel değişkenin özelliklerini bir değişkenle birleştirir: atandığı depolamanın diğer adıdır ref readonly ref ve readonly değiştirilemez.
Başvuru dönüşleri ve başvuru yerelleri örneği
Aşağıdaki örnek, ve Book olmak için iki alanı olan bir sınıf String Title Author tanımlar. Ayrıca, özel BookCollection bir nesne dizisi içeren bir sınıf Book tanımlar. Tek tek kitap nesneleri, yöntemi çağrılarak başvuruyla GetBookByTitle döndürülür.
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();
}
}
Çağıranın yöntemi tarafından döndürülen değeri ref yerel olarak depoladığı zaman, aşağıdaki örnekte de olduğu gibi çağıranın dönüş değerindeki GetBookByTitle BookCollection değişiklikleri nesnesine yansıtıldı.
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
C# dili belirtimi
Daha fazla bilgi edinmek için, bkz. C# Dil Belirtimi. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.