Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Varsayılan olarak, C# bağımsız değişkenleri değere göre işlevlere geçirir. Bu yaklaşım, değişkenin bir kopyasını yöntemine geçirir. Değer (struct) türleri için yöntemi değerin bir kopyasını alır. Başvuru (class) türleri için yöntemi başvurunun bir kopyasını alır. Bağımsız değişkenleri başvuruya göre geçirmek için parametre değiştiricileri kullanabilirsiniz.
Yapı bir değer türü olduğundan, bir yapıyı bir yönteme değere göre geçirme yöntemine bağımsız değişkenin bir kopyasını gönderir. yöntemi bu kopyayla çalışır. yöntemi, çağırma yöntemindeki özgün yapıya erişemez ve bunu değiştiremez. yöntemi yalnızca kopyayı değiştirebilir.
Sınıf örneği, değer türü değil başvuru türüdür. Bir yönteme değere göre bir başvuru türü geçirdiğinizde, yöntemi örneğe başvurunun bir kopyasını alır. Her iki değişken de aynı nesneye başvurur. parametresi, başvurunun bir kopyasıdır. Çağrılan yöntem, çağırma yöntemindeki örneği yeniden atayamıyor. Ancak, çağrılan yöntem örnek üyelerine erişmek için başvurunun kopyasını kullanabilir. Çağrılan yöntem bir örnek üyesini değiştirirse, çağıran yöntem aynı örneğe başvurdığından bu değişiklikleri de görür.
C# dili başvuru belgesi, C# dilinin en son yayımlanan sürümünü gösterir. Ayrıca, yaklaşan dil sürümü için genel önizlemelerdeki özelliklere yönelik ilk belgeleri içerir.
Belgelerde ilk olarak dilin son üç sürümünde veya geçerli genel önizlemelerde sunulan tüm özellikler tanımlanır.
Tavsiye
Bir özelliğin C# dilinde ilk tanıtıldığı zamanları bulmak için C# dil sürümü geçmişi makalesine bakın.
Değere göre geçiş ve başvuruya göre geçirme
Bu bölümdeki tüm örnekler, türler ve record türler arasındaki class farkları göstermek için aşağıdaki iki struct türü kullanır:
public record struct Point(int X, int Y);
// This doesn't use a primary constructor because the properties implemented for `record` types are
// readonly in record class types. That would prevent the mutations necessary for this example.
public record class Point3D
{
public int X { get; set; }
public int Y { get; set; }
public int Z { get; set; }
}
Aşağıdaki örneğin çıktısı, bir yapı türünü değere göre geçirme ile sınıf türünü değere göre geçirme arasındaki farkı gösterir. Her iki yöntem de Mutate bağımsız değişkenlerinin özellik değerlerini değiştirir. Parametre bir struct tür olduğunda, bu değişiklikler bağımsız değişkenin verilerinin bir kopyasını etkiler. Parametre bir class tür olduğunda, bu değişiklikler bağımsız değişkeninin başvurduğu örneği etkiler:
public class PassTypesByValue
{
public static void Mutate(Point pt)
{
Console.WriteLine($"\tEnter {nameof(Mutate)}:\t\t{pt}");
pt.X = 19;
pt.Y = 23;
Console.WriteLine($"\tExit {nameof(Mutate)}:\t\t{pt}");
}
public static void Mutate(Point3D pt)
{
Console.WriteLine($"\tEnter {nameof(Mutate)}:\t\t{pt}");
pt.X = 19;
pt.Y = 23;
pt.Z = 42;
Console.WriteLine($"\tExit {nameof(Mutate)}:\t\t{pt}");
}
public static void TestPassTypesByValue()
{
Console.WriteLine("===== Value Types =====");
var ptStruct = new Point { X = 1, Y = 2 };
Console.WriteLine($"After initialization:\t\t{ptStruct}");
Mutate(ptStruct);
Console.WriteLine($"After called {nameof(Mutate)}:\t\t{ptStruct}");
Console.WriteLine("===== Reference Types =====");
var ptClass = new Point3D { X = 1, Y = 2, Z = 3 };
Console.WriteLine($"After initialization:\t\t{ptClass}");
Mutate(ptClass);
Console.WriteLine($"After called {nameof(Mutate)}:\t\t{ptClass}");
// Output:
// ===== Value Types =====
// After initialization: Point { X = 1, Y = 2 }
// Enter Mutate: Point { X = 1, Y = 2 }
// Exit Mutate: Point { X = 19, Y = 23 }
// After called Mutate: Point { X = 1, Y = 2 }
// ===== Reference Types =====
// After initialization: Point3D { X = 1, Y = 2, Z = 3 }
// Enter Mutate: Point3D { X = 1, Y = 2, Z = 3 }
// Exit Mutate: Point3D { X = 19, Y = 23, Z = 42 }
// After called Mutate: Point3D { X = 19, Y = 23, Z = 42 }
}
}
ref Değiştirici, yöntemlere başvurarak bağımsız değişkenleri geçirmenin bir yoludur. Aşağıdaki kod önceki örneği çoğaltır, ancak parametreleri başvuruya göre geçirir. Tür üzerinde struct yapılan değişiklikler, yapı başvuruyla geçirildiğinde çağırma yönteminde görünür. Başvuru türü başvuruyla geçirildiğinde anlamsal bir değişiklik olmaz:
public class PassTypesByReference
{
public static void Mutate(ref Point pt)
{
Console.WriteLine($"\tEnter {nameof(Mutate)}:\t\t{pt}");
pt.X = 19;
pt.Y = 23;
Console.WriteLine($"\tExit {nameof(Mutate)}:\t\t{pt}");
}
public static void Mutate(ref Point3D pt)
{
Console.WriteLine($"\tEnter {nameof(Mutate)}:\t\t{pt}");
pt.X = 19;
pt.Y = 23;
pt.Z = 42;
Console.WriteLine($"\tExit {nameof(Mutate)}:\t\t{pt}");
}
public static void TestPassTypesByReference()
{
Console.WriteLine("===== Value Types =====");
var pStruct = new Point { X = 1, Y = 2 };
Console.WriteLine($"After initialization:\t\t{pStruct}");
Mutate(ref pStruct);
Console.WriteLine($"After called {nameof(Mutate)}:\t\t{pStruct}");
Console.WriteLine("===== Reference Types =====");
var pClass = new Point3D { X = 1, Y = 2, Z = 3 };
Console.WriteLine($"After initialization:\t\t{pClass}");
Mutate(ref pClass);
Console.WriteLine($"After called {nameof(Mutate)}:\t\t{pClass}");
// Output:
// ===== Value Types =====
// After initialization: Point { X = 1, Y = 2 }
// Enter Mutate: Point { X = 1, Y = 2 }
// Exit Mutate: Point { X = 19, Y = 23 }
// After called Mutate: Point { X = 19, Y = 23 }
// ===== Reference Types =====
// After initialization: Point3D { X = 1, Y = 2, Z = 3 }
// Enter Mutate: Point3D { X = 1, Y = 2, Z = 3 }
// Exit Mutate: Point3D { X = 19, Y = 23, Z = 42 }
// After called Mutate: Point3D { X = 19, Y = 23, Z = 42 }
}
}
Önceki örneklerde bir parametrenin özellikleri değiştirildi. Bir yöntem ayrıca bir parametreyi yeni bir değere yeniden atayabilir. Yeniden atama, değere veya başvuruya göre geçirildiğinde yapı ve sınıf türleri için farklı davranır. Aşağıdaki örnekte, değer tarafından geçirilen parametreler yeniden atandığında yapı türlerinin ve sınıf türlerinin nasıl davrandığı gösterilmektedir:
public class PassByValueReassignment
{
public static void Reassign(Point pt)
{
Console.WriteLine($"\tEnter {nameof(Reassign)}:\t\t{pt}");
pt = new Point { X = 13, Y = 29 };
Console.WriteLine($"\tExit {nameof(Reassign)}:\t\t{pt}");
}
public static void Reassign(Point3D pt)
{
Console.WriteLine($"\tEnter {nameof(Reassign)}:\t\t{pt}");
pt = new Point3D { X = 13, Y = 29, Z = -42 };
Console.WriteLine($"\tExit {nameof(Reassign)}:\t\t{pt}");
}
public static void TestPassByValueReassignment()
{
Console.WriteLine("===== Value Types =====");
var ptStruct = new Point { X = 1, Y = 2 };
Console.WriteLine($"After initialization:\t\t{ptStruct}");
Reassign(ptStruct);
Console.WriteLine($"After called {nameof(Reassign)}:\t\t{ptStruct}");
Console.WriteLine("===== Reference Types =====");
var ptClass = new Point3D { X = 1, Y = 2, Z = 3 };
Console.WriteLine($"After initialization:\t\t{ptClass}");
Reassign(ptClass);
Console.WriteLine($"After called {nameof(Reassign)}:\t\t{ptClass}");
// Output:
// ===== Value Types =====
// After initialization: Point { X = 1, Y = 2 }
// Enter Reassign: Point { X = 1, Y = 2 }
// Exit Reassign: Point { X = 13, Y = 29 }
// After called Reassign: Point { X = 1, Y = 2 }
// ===== Reference Types =====
// After initialization: Point3D { X = 1, Y = 2, Z = 3 }
// Enter Reassign: Point3D { X = 1, Y = 2, Z = 3 }
// Exit Reassign: Point3D { X = 13, Y = 29, Z = -42 }
// After called Reassign: Point3D { X = 1, Y = 2, Z = 3 }
}
}
Yukarıdaki örnekte, bir parametreyi yeni bir değere yeniden atadığınızda, türün bir değer türü veya başvuru türü olmasına bakılmaksızın bu değişikliğin çağrı yönteminden görülemediğini gösterir. Aşağıdaki örnekte, yöntemin başvuruyla aldığı bir parametreyi yeniden atadığınızda davranış gösterilmektedir:
public class PassByReferenceReassignment
{
public static void Reassign(ref Point pt)
{
Console.WriteLine($"\tEnter {nameof(Reassign)}:\t\t{pt}");
pt = new Point { X = 13, Y = 29 };
Console.WriteLine($"\tExit {nameof(Reassign)}:\t\t{pt}");
}
public static void Reassign(ref Point3D pt)
{
Console.WriteLine($"\tEnter {nameof(Reassign)}:\t\t{pt}");
pt = new Point3D { X = 13, Y = 29, Z = -42 };
Console.WriteLine($"\tExit {nameof(Reassign)}:\t\t{pt}");
}
public static void TestPassByReferenceReassignment()
{
Console.WriteLine("===== Value Types =====");
var ptStruct = new Point { X = 1, Y = 2 };
Console.WriteLine($"After initialization:\t\t{ptStruct}");
Reassign(ref ptStruct);
Console.WriteLine($"After called {nameof(Reassign)}:\t\t{ptStruct}");
Console.WriteLine("===== Reference Types =====");
var ptClass = new Point3D { X = 1, Y = 2, Z = 3 };
Console.WriteLine($"After initialization:\t\t{ptClass}");
Reassign(ref ptClass);
Console.WriteLine($"After called {nameof(Reassign)}:\t\t{ptClass}");
// Output:
// ===== Value Types =====
// After initialization: Point { X = 1, Y = 2 }
// Enter Reassign: Point { X = 1, Y = 2 }
// Exit Reassign: Point { X = 13, Y = 29 }
// After called Reassign: Point { X = 13, Y = 29 }
// ===== Reference Types =====
// After initialization: Point3D { X = 1, Y = 2, Z = 3 }
// Enter Reassign: Point3D { X = 1, Y = 2, Z = 3 }
// Exit Reassign: Point3D { X = 13, Y = 29, Z = -42 }
// After called Reassign: Point3D { X = 13, Y = 29, Z = -42 }
}
}
Yukarıdaki örnekte, başvuru tarafından geçirilen bir parametrenin değerinin yeniden atandığı çağrı bağlamında nasıl görünür olduğu gösterilmektedir.
Başvuruların ve değerlerin güvenli bağlamı
Yöntemler, parametrelerin değerlerini alanlarda depolayabilir. Parametreleri değere göre geçirdiğinizde genellikle güvenlidir. yöntemi değerleri kopyalar ve yöntem bunları bir alanda depoladığında başvuru türlerine erişilebilir. Parametreleri başvuruya göre güvenli bir şekilde geçirmek için derleyicinin yeni bir değişkene başvuru atamanın ne zaman güvenli olduğunu tanımlaması gerekir. Derleyici, her ifade için bir ifadeye veya değişkene erişimi sınırlayan güvenli bir bağlam tanımlar. Derleyici iki kapsam kullanır: safe-context ve ref-safe-context.
- Güvenli bağlam, herhangi bir ifadeye güvenli bir şekilde erişilebileceği kapsamı tanımlar.
- ref-safe-context, herhangi bir ifadeye yapılan başvuruya güvenli bir şekilde erişilebileceği veya değiştirilebileceği kapsamı tanımlar.
Resmi olmayan bir şekilde, bu kapsamları kodunuzun artık geçerli olmayan bir başvuruya asla erişmediğinden veya başvuruyu değiştirmediğinden emin olmak için bir mekanizma olarak düşünebilirsiniz. Başvuru, geçerli bir nesneye veya yapıya başvurduğu sürece geçerlidir. Güvenli bağlam , bir değişkenin ne zaman atanabileceğini veya yeniden atanabileceğini tanımlar. ref-safe-context, bir değişkenin ne zaman başv atanabileceğini veya yeniden atanabileceğini tanımlar. Atama yeni bir değere değişken atar; başvuru ataması, değişkeni farklı bir depolama konumuna başvurmak üzere atar.
Başvuru parametreleri
Bağımsız değişkenleri değer yerine başvuruya göre geçirmek için parametre bildiriminde aşağıdaki değiştiricilerden birini kullanın:
-
ref: yöntemini çağırmadan önce bağımsız değişkeni başlatın. yöntemi parametresine yeni bir değer atayabilir, ancak bunun için gerekli değildir. -
out: Yöntemini çağırmadan önce çağıran yöntemin bağımsız değişkeni başlatması gerekmez. yöntemi parametresine bir değer atamalıdır. -
ref readonly: yöntemini çağırmadan önce bağımsız değişkeni başlatın. yöntemi parametresine yeni bir değer atayamaz. -
in: yöntemini çağırmadan önce bağımsız değişkeni başlatın. yöntemi parametresine yeni bir değer atayamaz. Derleyici, parametrelere bağımsız değişkenin bir kopyasını tutmak içiningeçici bir değişken oluşturabilir.
Başvuru tarafından geçirilen parametre bir başvuru değişkenidir. Kendi değeri yoktur. Bunun yerine, başvuran adlı farklı bir değişkene başvurur. Başvuru değişkenlerini yeniden atayabilirsiniz ve bu da başvuru değişkenlerini değiştirir.
Bir sınıfın üyeleri yalnızca , , refref readonlyveya inile outfarklı imzalara sahip olamaz. Bir türün iki üyesi arasındaki tek fark bir üyenin parametresi, diğer üyenin ref ise bir , ref readonlyveya in parametresi olmasıysa outderleyici hatası oluşur. Ancak, aşağıdaki örnekte gösterildiği gibi bir yöntemin ref, ref readonly, inveya out parametresi olduğunda ve diğer yöntemde değer tarafından geçirilen bir parametre olduğunda yöntemleri aşırı yükleyebilirsiniz. Gizlenmesi veya geçersiz kılınması ingibi imza eşleştirmesi gerektiren diğer durumlarda , ref, ref readonlyve out imzanın bir parçasıdır ve birbiriyle eşleşmez.
Bir parametre önceki değiştiricilerden birine sahip olduğunda, ilgili bağımsız değişkenin uyumlu bir değiştiricisi olabilir:
- Parametrenin
refbağımsız değişkeni değiştiriciyirefiçermelidir. - Parametrenin
outbağımsız değişkeni değiştiriciyioutiçermelidir. - Bir parametrenin
inbağımsız değişkeni isteğe bağlı olarak değiştiriciyiiniçerebilir.refBunun yerine değiştirici bağımsız değişkende kullanılıyorsa, derleyici bir uyarı yayınlar. - Bir parametrenin
ref readonlybağımsız değişkeni veyaindeğiştiricilerinirefiçermelidir, ancak ikisini birden içermemelidir. Hiçbir değiştirici dahil değilse, derleyici bir uyarı görüntüler.
Bu değiştiricileri kullandığınızda, bağımsız değişkenin nasıl kullanıldığını açıklar:
-
ref, yöntemin bağımsız değişkenin değerini okuyabileceği veya yazabileceği anlamına gelir. -
outyöntemi bağımsız değişkenin değerini ayarlar anlamına gelir. -
ref readonlyyöntemi okur ancak bağımsız değişkenin değerini yazamaz anlamına gelir. Bağımsız değişken başvuruyla geçirilmelidir . -
inyöntemi okur ancak bağımsız değişkenin değerini yazamaz anlamına gelir. Bağımsız değişken başvuru veya geçici bir değişken aracılığıyla geçirilir.
Önceki parametre değiştiricilerini aşağıdaki yöntem türlerinde kullanamazsınız:
- Zaman uyumsuz değiştiriciyi kullanarak tanımladığınız zaman uyumsuz yöntemler.
- Verim dönüşünüyineleyici yöntemleri.
Uzantı üyelerinin bu bağımsız değişken anahtar sözcüklerinin kullanımıyla ilgili kısıtlamaları da vardır:
- Anahtar
outsözcüğü bir uzantı yönteminin ilk bağımsız değişkeninde kullanılamaz. - Bağımsız
refdeğişken , veya yapı olarak kısıtlanmamış genel birstructtür olmadığında, anahtar sözcüğü uzantı yönteminin ilk bağımsız değişkeninde kullanılamaz. -
ref readonlyİlk bağımsız değişken birinolmadığı sürece vestructanahtar sözcükleri kullanılamaz. -
ref readonlyveinanahtar sözcükleri, yapı olarak kısıtlanmış olsa bile herhangi bir genel türde kullanılamaz.
Özellikler değişken değildir. Bunlar yöntemdir. Özellikleri parametreler için ref bağımsız değişken olarak kullanamazsınız.
ref parametre değiştirici
Parametre kullanmak ref için, aşağıdaki örnekte gösterildiği gibi hem yöntem tanımı hem de çağırma yöntemi açıkça anahtar sözcüğünü ref kullanmalıdır. (COM çağrısı yapılırken çağıran yöntemin atlanabilir ref olması dışında.)
void Method(ref int refArgument)
{
refArgument = refArgument + 44;
}
int number = 1;
Method(ref number);
Console.WriteLine(number);
// Output: 45
Bir parametreye ref geçirmeden önce bir bağımsız değişken başlatmanız gerekir.
out parametre değiştirici
Parametre out kullanmak için hem yöntem tanımının hem de çağıran yöntemin açıkça anahtar sözcüğünü out kullanması gerekir. Örneğin:
int initializeInMethod;
OutArgExample(out initializeInMethod);
Console.WriteLine(initializeInMethod); // value is now 44
void OutArgExample(out int number)
{
number = 44;
}
Yöntem çağrısından önce bağımsız değişken olarak out geçirilen değişkenleri başlatmanız gerekmez. Ancak, çağrılan yöntemin döndürmeden önce bir değer ataması gerekir.
Deconstruct yöntemleri, birden çok değer döndürmek için değiştirici ile out parametrelerini bildirir. Diğer yöntemler birden çok dönüş değeri için değer demetleri döndürebilir.
Değişkeni bağımsız değişken olarak geçirmeden önce ayrı bir out deyimde bildirebilirsiniz. Değişkeni, ayrı bir değişken bildirimi yerine yöntem çağrısının bağımsız değişken listesinde de bildirebilirsiniz out .
out değişken bildirimleri daha kompakt, okunabilir kod üretir ve ayrıca yöntem çağrısından önce değişkene yanlışlıkla bir değer atamanızı önler. Aşağıdaki örnek, Int32.TryParsenumberdeğişkeni tanımlar.
string numberAsString = "1640";
if (Int32.TryParse(numberAsString, out int number))
Console.WriteLine($"Converted '{numberAsString}' to {number}");
else
Console.WriteLine($"Unable to convert '{numberAsString}'");
// The example displays the following output:
// Converted '1640' to 1640
Örtük olarak yazılan bir yerel değişken de bildirebilirsiniz.
ref readonly Değiştirici
Yöntem bildirimi, değiştiriciyi ref readonly gerektirir. Arama sitesindeki değiştirici isteğe bağlıdır. veya ref değiştiricisini in kullanabilirsiniz. Değiştirici ref readonly , arama sitesinde geçerli değil. Çağrı sitesinde kullandığınız değiştirici, bağımsız değişkenin özelliklerini açıklamaya yardımcı olabilir. Yalnızca bağımsız değişken bir değişkense ve yazılabilirse kullanabilirsiniz ref . Yalnızca bağımsız değişken bir değişken olduğunda kullanabilirsiniz in . Değişken yazılabilir veya salt okunur olabilir. Bağımsız değişken bir değişken değilse ancak bir ifadeyse iki değiştiriciyi de ekleyemezsiniz. Aşağıdaki örneklerde bu koşullar gösterilmektedir. Aşağıdaki yöntem, performans nedenleriyle büyük bir yapının başvuruyla geçirilmesi gerektiğini belirtmek için değiştiriciyi kullanır ref readonly :
public static void ForceByRef(ref readonly OptionStruct thing)
{
// elided
}
veya in değiştiricisini kullanarak ref yöntemini çağırabilirsiniz. Değiştiriciyi atlarsanız, derleyici bir uyarı görüntüler. Bağımsız değişken değişken değil de bir ifade olduğunda, veya in değiştiricilerini ref ekleyemezsiniz, bu nedenle uyarıyı gizlemeniz gerekir:
ForceByRef(in options);
ForceByRef(ref options);
ForceByRef(options); // Warning! variable should be passed with `ref` or `in`
ForceByRef(new OptionStruct()); // Warning, but an expression, so no variable to reference
Değişken bir readonly değişkense değiştiriciyi in kullanmanız gerekir. Bunun yerine değiştiriciyi ref kullanırsanız derleyici bir hata döndürür.
değiştirici, ref readonly yöntemin bağımsız değişkenin değişken olmayan bir ifade yerine değişken olmasını beklediğini belirtir. Değişken olmayan ifadelere örnek olarak sabitler, yöntem dönüş değerleri ve özellikler verilebilir. Bağımsız değişken bir değişken değilse, derleyici bir uyarı görüntüler.
in parametre değiştirici
in Değiştirici yöntem bildiriminde gereklidir, ancak çağrı sitesinde gereksizdir.
var largeStruct = new LargeStruct { Value1 = 42, Value2 = 3.14, Value3 = "Hello" };
// Using 'in' avoids copying the large struct and prevents modification
ProcessLargeStruct(in largeStruct);
Console.WriteLine($"Original value unchanged: {largeStruct.Value1}");
// Without 'in', the struct would be copied (less efficient for large structs)
ProcessLargeStructByValue(largeStruct);
Console.WriteLine($"Original value still unchanged: {largeStruct.Value1}");
void ProcessLargeStruct(in LargeStruct data)
{
// Can read the values
Console.WriteLine($"Processing: {data.Value1}, {data.Value2}, {data.Value3}");
// Uncomment the following line to see error CS8331
// data.Value1 = 99; // Compilation error: cannot assign to 'in' parameter
}
void ProcessLargeStructByValue(LargeStruct data)
{
// This method receives a copy of the struct
Console.WriteLine($"Processing copy: {data.Value1}, {data.Value2}, {data.Value3}");
// Modifying the copy doesn't affect the original
data.Value1 = 99;
}
Değiştirici, in derleyicinin bağımsız değişken için geçici bir değişken oluşturmasını ve bu bağımsız değişkene salt okunur bir başvuru geçirmesini sağlar. Bağımsız değişkenin dönüştürülmesi gerektiğinde, bağımsız değişken türünden örtük bir dönüştürme olduğunda veya bağımsız değişken değişken olmayan bir değer olduğunda, derleyici her zaman geçici bir değişken oluşturur. Örneğin, bağımsız değişken değişmez değer olduğunda veya özellik erişimcisinden döndürülen değer olduğunda. API'niz bağımsız değişkenin başvuruya göre geçirilmesini gerektirdiğinde ref readonly , değiştirici yerine değiştiriciyi in seçin.
Parametrelerle in yöntemler tanımlayarak performans iyileştirmesi elde edebilirsiniz. Bazı struct tür bağımsız değişkenlerin boyutu büyük olabilir ve sıkı döngülerde veya kritik kod yollarında yöntemleri çağırdığınızda, bu yapıları kopyalamanın maliyeti önemli olur.
in Çağrılan yöntem bu bağımsız değişkenin durumunu değiştirmediğinden, bağımsız değişkenleri başvuruya göre güvenli bir şekilde geçirebileceğinizi belirtmek için parametreleri bildirin. Bu bağımsız değişkenleri başvuruya göre geçirmek(potansiyel olarak) pahalı kopyayı önler. Bağımsız değişkenin in değere göre değil başvuruya göre geçirildiğinden emin olmak için arama sitesine değiştiriciyi açıkça eklersiniz. Açıkça kullanarak in aşağıdaki iki etkiye sahiptir:
- Çağrı sitesinde belirtilmesi
in, derleyiciyi eşleşeninparametreyle tanımlanan bir yöntemi seçmeye zorlar. Aksi takdirde, iki yöntem yalnızca varlığındainfarklılık gösterdiğinde, değere göre aşırı yükleme daha iyi bir eşleşmedir. - belirterek
in, başvuruya göre bir bağımsız değişken geçirme amacınızı bildirirsiniz. ileinkullanılan bağımsız değişken, doğrudan başvurulabilen bir konumu temsil etmelidir. veoutbağımsız değişkenleri içinrefaynı genel kurallar geçerlidir: Sabitleri, normal özellikleri veya değer üreten diğer ifadeleri kullanamazsınız. Aksi takdirde, çağrı sitesinde atlanmasıinderleyiciye yönteme salt okunur başvuru ile geçici bir değişken oluşturmanın uygun olduğunu bildirir. Derleyici, bağımsız değişkenlerleinçeşitli kısıtlamaların üstesinden gelmek için geçici bir değişken oluşturur:- Geçici değişken, derleme zamanı sabitlerini parametre olarak
insağlar. - Geçici değişken, parametreler için
inözelliklere veya diğer ifadelere izin verir. - Geçici değişken, bağımsız değişken türünden parametre türüne örtük dönüştürmenin olduğu bağımsız değişkenlere izin verir.
- Geçici değişken, derleme zamanı sabitlerini parametre olarak
Yukarıdaki tüm örneklerde, derleyici sabit, özellik veya başka bir ifadenin değerini depolayan geçici bir değişken oluşturur.
Aşağıdaki kodda bu kurallar gösterilmektedir:
static void Method(in int argument)
{
// implementation removed
}
Method(5); // OK, temporary variable created.
Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // OK, temporary int created with the value 0
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // passed by readonly reference
Method(in i); // passed by readonly reference, explicitly using `in`
Şimdi, değere göre bağımsız değişkenleri kullanan başka bir yöntemin kullanılabilir olduğunu varsayalım. Sonuçlar aşağıdaki kodda gösterildiği gibi değişir:
static void Method(int argument)
{
// implementation removed
}
static void Method(in int argument)
{
// implementation removed
}
Method(5); // Calls overload passed by value
Method(5L); // CS1503: no implicit conversion from long to int
short s = 0;
Method(s); // Calls overload passed by value.
Method(in s); // CS1503: cannot convert from in short to in int
int i = 42;
Method(i); // Calls overload passed by value
Method(in i); // passed by readonly reference, explicitly using `in`
Bağımsız değişkenin başvuruyla geçirildiği tek yöntem çağrısı, son çağrıdır.
Not
Önceki kod basitlik için bağımsız değişken türü olarak kullanır int .
int Çoğu modern makinede başvurudan büyük olmadığından, tek int bir başvurudan salt okunur başvuru geçirmenin bir avantajı yoktur.
params Değiştirici
anahtar sözcüğüne params sahip parametre, yöntem bildirimindeki son parametre olmalıdır. Yöntem bildiriminde yalnızca bir anahtar sözcük kullanabilirsiniz params .
Parametresini params bir koleksiyon türü olarak bildirmeniz gerekir. Tanınan koleksiyon türleri şunlardır:
- Öğe türünün
T[]olduğu tek boyutlu dizi türü.T - Bir span türü:
System.Span<T>System.ReadOnlySpan<T>
Bu türlerde , öğe türü şeklindedirT.
- İlgili öğe türüne sahip erişilebilir oluşturma yöntemine sahip bir tür. create yöntemi, koleksiyon ifadeleriyle aynı özniteliği kullanır.
- Aşağıdaki durumlarda uygulayan bir yapı veya System.Collections.Generic.IEnumerable<T>:
- türü bağımsız değişken olmadan çağırabileceğiniz bir oluşturucuya sahiptir ve oluşturucu en az bildirimde bulunan üye kadar erişilebilirdir.
- türü, aşağıdaki durumlarda bir örnek (uzantı değil) yöntemine
Addsahiptir:- yöntemi tek bir değer bağımsız değişkeniyle çağrılabilir.
- Yöntem genelse, tür bağımsız değişkenleri bağımsız değişkenden çıkarılabilir.
- yöntemi en az bildirimde bulunan üye kadar erişilebilir. Bu durumda, öğe türü türün yineleme türüdür.
- Arabirim türü:
C# 13'e geçmeden önce, parametresi için tek boyutlu bir dizi kullanmanız gerekir.
Parametresi olan params bir yöntemi çağırdığınızda şunları geçirebilirsiniz:
- Dizi öğelerinin türündeki bağımsız değişkenlerin virgülle ayrılmış listesi.
- Belirtilen türdeki bağımsız değişkenler koleksiyonu.
- Bağımsız değişken yok. Bağımsız değişken göndermezseniz, listenin
paramsuzunluğu sıfır olur.
Aşağıdaki örnekte bir parametreye bağımsız değişken göndermenin çeşitli yolları gösterilmektedir params .
public static void ParamsModifierExample(params int[] list)
{
for (int i = 0; i < list.Length; i++)
{
System.Console.Write(list[i] + " ");
}
System.Console.WriteLine();
}
public static void ParamsModifierObjectExample(params object[] list)
{
for (int i = 0; i < list.Length; i++)
{
System.Console.Write(list[i] + " ");
}
System.Console.WriteLine();
}
public static void TryParamsCalls()
{
// You can send a comma-separated list of arguments of the
// specified type.
ParamsModifierExample(1, 2, 3, 4);
ParamsModifierObjectExample(1, 'a', "test");
// A params parameter accepts zero or more arguments.
// The following calling statement displays only a blank line.
ParamsModifierObjectExample();
// An array argument can be passed, as long as the array
// type matches the parameter type of the method being called.
int[] myIntArray = { 5, 6, 7, 8, 9 };
ParamsModifierExample(myIntArray);
object[] myObjArray = { 2, 'b', "test", "again" };
ParamsModifierObjectExample(myObjArray);
// The following call causes a compiler error because the object
// array cannot be converted into an integer array.
//ParamsModifierExample(myObjArray);
// The following call does not cause an error, but the entire
// integer array becomes the first element of the params array.
ParamsModifierObjectExample(myIntArray);
}
/*
Output:
1 2 3 4
1 a test
5 6 7 8 9
2 b test again
System.Int32[]
*/
Bir parametrenin bağımsız değişkeni params bir koleksiyon türü olduğunda aşırı yükleme çözümlemesi belirsizliğe neden olabilir. Bağımsız değişkenin koleksiyon türü, parametrenin koleksiyon türüne dönüştürülebilir olmalıdır. Farklı aşırı yüklemeler bu parametre için daha iyi dönüştürmeler sağladığında, bu yöntem daha iyi olabilir. Ancak, parametrenin params bağımsız değişkeni ayrık öğelerse veya eksikse, farklı params parametre türlerine sahip tüm aşırı yüklemeler bu parametre için eşittir.
Daha fazla bilgi için C# Dil Belirtimi'ndekiBağımsız Değişken listelerindeki bölüme bakın. Dil belirtimi, C# sözdizimi ve kullanımı için kesin bir kaynaktır.