Yöntemler (C# Programlama Kılavuzu)
Yöntem, bir dizi deyim içeren bir kod bloğudur. Program, yöntemini çağırarak ve gerekli yöntem bağımsız değişkenlerini belirterek deyimlerin yürütülmesine neden olur. C# dilinde, yürütülen her yönerge bir yöntem bağlamında gerçekleştirilir.
Main
yöntemi her C# uygulamasının giriş noktasıdır ve program başlatıldığında ortak dil çalışma zamanı (CLR) tarafından çağrılır. Üst düzey deyimleri kullanan bir uygulamada, Main
yöntemi derleyici tarafından oluşturulur ve tüm üst düzey deyimleri içerir.
Not
Bu makalede adlandırılmış yöntemler ele alınmaktadır. Anonim işlevler hakkında bilgi için bkz . Lambda ifadeleri.
Yöntem imzaları
Yöntemler, veya gibi public
private
erişim düzeyi, veya gibi isteğe bağlı değiştiriciler abstract
sealed
, dönüş değeri, yöntemin adı ve herhangi bir yöntem parametresi belirtilerek bir sınıf, yapı veya arabirimde bildirilir. Bu parçalar birlikte yönteminin imzasıdır.
Önemli
Yöntemin dönüş türü, yöntemi aşırı yükleme amacıyla yöntemin imzasının bir parçası değildir. Ancak, bir temsilci ile işaret eden yöntem arasındaki uyumluluğu belirlerken yöntemin imzasının bir parçasıdır.
Yöntem parametreleri parantez içine alınır ve virgülle ayrılır. Boş ayraçlar yöntemin parametre gerektirmediğini gösterir. Bu sınıf dört yöntem içerir:
abstract class Motorcycle
{
// Anyone can call this.
public void StartEngine() {/* Method statements here */ }
// Only derived classes can call this.
protected void AddGas(int gallons) { /* Method statements here */ }
// Derived classes can override the base class implementation.
public virtual int Drive(int miles, int speed) { /* Method statements here */ return 1; }
// Derived classes must implement this.
public abstract double GetTopSpeed();
}
Yöntem erişimi
Nesne üzerinde yöntem çağırmak, bir alana erişmek gibidir. Nesne adından sonra bir nokta, yöntemin adı ve parantezler ekleyin. Bağımsız değişkenler parantez içinde listelenir ve virgülle ayrılır. Bu nedenle sınıfının yöntemleri Motorcycle
aşağıdaki örnekte olduğu gibi çağrılabilir:
class TestMotorcycle : Motorcycle
{
public override double GetTopSpeed()
{
return 108.4;
}
static void Main()
{
TestMotorcycle moto = new TestMotorcycle();
moto.StartEngine();
moto.AddGas(15);
moto.Drive(5, 20);
double speed = moto.GetTopSpeed();
Console.WriteLine("My top speed is {0}", speed);
}
}
Yöntem parametreleri ile bağımsız değişkenler karşılaştırması
Yöntem tanımı, gerekli parametrelerin adlarını ve türlerini belirtir. Kodu çağırırken yöntemini çağırırken, her parametre için bağımsız değişken olarak adlandırılan somut değerler sağlar. Bağımsız değişkenlerin parametre türüyle uyumlu olması gerekir, ancak çağıran kodda kullanılan bağımsız değişken adının (varsa) yönteminde tanımlanan parametreyle aynı olması gerekmez. Örneğin:
public void Caller()
{
int numA = 4;
// Call with an int variable.
int productA = Square(numA);
int numB = 32;
// Call with another int variable.
int productB = Square(numB);
// Call with an integer literal.
int productC = Square(12);
// Call with an expression that evaluates to int.
productC = Square(productA * 3);
}
int Square(int i)
{
// Store input argument in a local variable.
int input = i;
return input * input;
}
Başvuruya göre geçirme ile değere göre geçirme karşılaştırması
Varsayılan olarak, bir değer türünün örneği bir yönteme geçirildiğinde, örneğin kendisi yerine kopyası geçirilir. Bu nedenle, bağımsız değişkende yapılan değişikliklerin çağırma yöntemindeki özgün örneği üzerinde hiçbir etkisi yoktur. Bir değer türü örneğini başvuruya göre geçirmek için anahtar sözcüğünü ref
kullanın. Daha fazla bilgi için bkz . Değer Türü Parametrelerini Geçirme.
Bir başvuru türündeki bir nesne bir yönteme geçirildiğinde, nesneye bir başvuru geçirilir. Başka bir ifadeyle, yöntemi nesnenin kendisini değil, nesnenin konumunu gösteren bir bağımsız değişken alır. Bu başvuruyu kullanarak nesnenin bir üyesini değiştirirseniz, nesneyi değere göre geçirseniz bile, değişiklik çağırma yöntemindeki bağımsız değişkene yansıtılır.
Aşağıdaki örnekte gösterildiği gibi anahtar sözcüğünü class
kullanarak bir başvuru türü oluşturursunuz:
public class SampleRefType
{
public int value;
}
Şimdi, bu türü temel alan bir nesneyi bir yönteme geçirirseniz, nesneye bir başvuru geçirilir. Aşağıdaki örnek türündeki SampleRefType
bir nesneyi yöntemine ModifyObject
geçirir:
public static void TestRefType()
{
SampleRefType rt = new SampleRefType();
rt.value = 44;
ModifyObject(rt);
Console.WriteLine(rt.value);
}
static void ModifyObject(SampleRefType obj)
{
obj.value = 33;
}
Örnek temelde, bir bağımsız değişkeni değere göre bir yönteme geçirmesindeki önceki örnektekiyle aynı işlemi yapar. Ancak başvuru türü kullanıldığından sonuç farklıdır. parametresinin alanında yapılan ModifyObject
değişiklik, obj
yöntemindeki bağımsız değişkeninin TestRefType
rt
alanını da değiştirirvalue
.value
yöntemi çıkış TestRefType
olarak 33 görüntüler.
Başvuru türlerini başvuruya ve değere göre geçirme hakkında daha fazla bilgi için bkz . Başvuru Türü Parametrelerini ve Başvuru Türlerini Geçirme.
Dönüş değerleri
Yöntemler çağırana bir değer döndürebilir. Dönüş türü (yöntem adından önce listelenen tür) değilsevoid
, yöntemi deyimini return
kullanarak değeri döndürebilir. Anahtar sözcüğü ve return
ardından dönüş türüyle eşleşen bir değer içeren bir deyim, bu değeri yöntem çağırana döndürür.
Değer, çağırana değere veya başvuruya göre döndürülebilir. Anahtar sözcük yöntem imzasında kullanılıyorsa ref
ve her return
anahtar sözcüğü takip ederse, değerler çağırana başvuruyla döndürülür. Örneğin, aşağıdaki yöntem imzası ve return deyimi, yöntemin çağırana başvuruyla adlandırılmış estDistance
bir değişken döndürdüğünü gösterir.
public ref double GetEstimatedDistance()
{
return ref estDistance;
}
anahtar return
sözcüğü, yönteminin yürütülmesini de durdurur. Dönüş türü ise void
, değeri olmayan bir return
deyim yine de yönteminin yürütülmesini durdurmak için yararlıdır. return
anahtar sözcüğü olmadan, yöntem kod bloğunun sonuna ulaştığında yürütmeyi durdurur. Bir değer döndürmek için anahtar sözcüğünü return
kullanmak için geçersiz olmayan dönüş türüne sahip yöntemler gereklidir. Örneğin, bu iki yöntem tamsayıları döndürmek için anahtar sözcüğünü return
kullanır:
class SimpleMath
{
public int AddTwoNumbers(int number1, int number2)
{
return number1 + number2;
}
public int SquareANumber(int number)
{
return number * number;
}
}
Bir yöntemden döndürülen bir değeri kullanmak için çağıran yöntem, aynı türdeki bir değerin yeterli olduğu her yerde yöntem çağrısının kendisini kullanabilir. Dönüş değerini bir değişkene de atayabilirsiniz. Örneğin, aşağıdaki iki kod örneği aynı hedefi gerçekleştirir:
int result = obj.AddTwoNumbers(1, 2);
result = obj.SquareANumber(result);
// The result is 9.
Console.WriteLine(result);
result = obj.SquareANumber(obj.AddTwoNumbers(1, 2));
// The result is 9.
Console.WriteLine(result);
Bu örnekte result
, bir değeri depolamak için yerel değişken kullanmak isteğe bağlıdır. Kodun okunabilirliğine yardımcı olabilir veya yöntemin tüm kapsamı için bağımsız değişkenin özgün değerini depolamanız gerekiyorsa gerekli olabilir.
Bir yöntemden başvuru tarafından döndürülen bir değeri kullanmak için, değerini değiştirmek istiyorsanız bir başvuru yerel değişkeni bildirmeniz gerekir. Örneğin, yöntem başvuruya Planet.GetEstimatedDistance
göre bir Double değer döndürürse, bunu aşağıdaki gibi kodla bir başvuru yerel değişkeni olarak tanımlayabilirsiniz:
ref double distance = ref Planet.GetEstimatedDistance();
Çağıran işlev diziyi M
içine geçirdiyse, M
dizinin içeriğini değiştiren bir yönteminden çok boyutlu bir dizi döndürmek gerekli değildir. İyi stil veya işlevsel değer akışı için dizinin M
sonucunu döndürebilirsiniz, ancak C# tüm başvuru türlerini değere göre geçirdiğinden ve dizi başvurusunun değeri dizinin işaretçisidir. yönteminde M
, dizinin içeriğinde yapılan tüm değişiklikler, aşağıdaki örnekte gösterildiği gibi diziye başvurusu olan herhangi bir kod tarafından gözlemlenebilir:
static void Main(string[] args)
{
int[,] matrix = new int[2, 2];
FillMatrix(matrix);
// matrix is now full of -1
}
public static void FillMatrix(int[,] matrix)
{
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
matrix[i, j] = -1;
}
}
}
Zaman uyumsuz yöntemler
Zaman uyumsuz özelliği kullanarak, açık geri çağırmalar kullanmadan veya kodunuzu birden çok yönteme veya lambda ifadesine el ile bölmeden zaman uyumsuz yöntemleri çağırabilirsiniz.
Bir yöntemi zaman uyumsuz değiştirici ile işaretlerseniz yönteminde await işlecini kullanabilirsiniz. Denetim zaman uyumsuz yöntemde bir await ifadesine ulaştığında, denetim çağırana döner ve yöntemdeki ilerleme, beklenen görev tamamlanana kadar askıya alınır. Görev tamamlandığında, yürütme yönteminde devam edebilir.
Not
Zaman uyumsuz yöntem, henüz tamamlanmamış ilk beklenen nesneyle karşılaştığında veya zaman uyumsuz yöntemin sonuna ulaştığında (hangisi önce gerçekleşirse) çağırana geri döner.
Zaman uyumsuz yöntem genellikle , TaskIAsyncEnumerable<T>veya void
dönüş türüne Task<TResult>sahiptir. Dönüş void
türü öncelikli olarak bir dönüş türünün gerekli olduğu void
olay işleyicilerini tanımlamak için kullanılır. Döndüren void
zaman uyumsuz bir yöntem beklenemez ve void-dönüş yöntemini çağıran yöntemin attığı özel durumları yakalayamaz. Zaman uyumsuz bir yöntem herhangi bir görev benzeri dönüş türüne sahip olabilir.
Aşağıdaki örnekte, DelayAsync
dönüş türü olan zaman uyumsuz bir yöntemdir Task<TResult>. DelayAsync
tamsayı döndüren bir return
deyime sahiptir. Bu nedenle yöntemi bildiriminin DelayAsync
dönüş türü Task<int>
olmalıdır. dönüş türü olduğundan Task<int>
, içindeki ifadenin await
DoSomethingAsync
değerlendirilmesi, aşağıdaki deyimin gösterdiği gibi bir tamsayı oluşturur: int result = await delayTask
.
Main
yöntemi, dönüş türü olan zaman uyumsuz bir yöntem örneğidirTask. yöntemine DoSomethingAsync
gider ve tek bir satırla ifade edildiğinden async
ve await
anahtar sözcüklerini atlayabilir. Zaman DoSomethingAsync
uyumsuz bir yöntem olduğundan, aşağıdaki deyimde gösterildiği gibi çağrısının DoSomethingAsync
görevi beklenmelidir: await DoSomethingAsync();
.
class Program
{
static Task Main() => DoSomethingAsync();
static async Task DoSomethingAsync()
{
Task<int> delayTask = DelayAsync();
int result = await delayTask;
// The previous two statements may be combined into
// the following statement.
//int result = await DelayAsync();
Console.WriteLine($"Result: {result}");
}
static async Task<int> DelayAsync()
{
await Task.Delay(100);
return 5;
}
}
// Example output:
// Result: 5
Zaman uyumsuz bir yöntem herhangi bir ref veya out parametresi bildiremez, ancak bu tür parametreleri olan yöntemleri çağırabilir.
Zaman uyumsuz yöntemler hakkında daha fazla bilgi için bkz . Async ve await ile zaman uyumsuz programlama ve Zaman uyumsuz dönüş türleri.
İfade gövdesi tanımları
Bir ifadenin sonucuyla hemen döndürülen veya yöntemin gövdesi olarak tek bir deyimi olan yöntem tanımlarının olması yaygın bir durumdur. kullanarak =>
bu tür yöntemleri tanımlamak için bir söz dizimi kısayolu vardır:
public Point Move(int dx, int dy) => new Point(x + dx, y + dy);
public void Print() => Console.WriteLine(First + " " + Last);
// Works with operators, properties, and indexers too.
public static Complex operator +(Complex a, Complex b) => a.Add(b);
public string Name => First + " " + Last;
public Customer this[long id] => store.LookupCustomer(id);
Yöntem döndürüyorsa void
veya zaman uyumsuz bir yöntemse, yöntemin gövdesi bir deyim ifadesi olmalıdır (lambda'larla aynı şekilde). Özellikler ve dizin oluşturucular için bunlar salt okunur olmalıdır ve erişimci anahtar sözcüğünü get
kullanmazsınız.
Yineleyiciler
Yineleyici, liste veya dizi gibi bir koleksiyon üzerinde özel bir yineleme gerçekleştirir. Yineleyici, her öğeyi birer birer döndürmek için yield return deyimini kullanır. Bir yield return
deyime ulaşıldığında koddaki geçerli konum hatırlanır. Yineleyici bir sonraki sefer çağrıldığında yürütme bu konumdan yeniden başlatılır.
Foreach deyimini kullanarak istemci kodundan yineleyici çağırırsınız.
Yineleyicinin dönüş türü , , IEnumerable<T>, IAsyncEnumerable<T>IEnumeratorveya IEnumerator<T>olabilirIEnumerable.
Daha fazla bilgi için bkz . Yineleyiciler.
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.