C# ref ve out Parametreleri Kullanımı

C# dilinde argümanları bu argümanların türlerine göre metotlara iki şekilde aktarabiliriz.

1-Değere Göre: Değer tipindeki bir argümanı metot parametrelerine aktarırken bu argümanın bir kopyası oluşturulur ve bu kopya metot tarafından kullanılır. Böyle bir kullanım tahmin edeceğiniz gibi esas argüman üzerinde herhangi bir değişikliğe neden olmaz. Aşağıdaki kodu inceleyelim:

static int Metot1(int a)
{
return a+1;
}
static void Main()
{
int b = 5;
int c = Metot1(b);
Console.WriteLine("b = {0}nc = {1}",b,c);
Console.ReadLine();
}

Ekran Çıktısı:

b = 5
c = 6

metot_deger_tipi

1- Bildiğiniz gibi programımızı derlediğimizde program Main metodundan başlayarak derlenmeye başlar. Buna göre ilk satıra geldiğinde int tipinden bir b değişkeni için hafızanın stack bölgesinde değeri 5 olacak şekilde yer ayırır.

2- Bir sonraki satıra geldiğinde int tipinden bir c değişkenine Metot1 isimli metottan geri dönen bir değeri atadığımızı görür, Metot1 metodundan geri dönen değeri hesaplamak için programımızda Metot1’in tanımının bulunduğu satıra geçer ve Metot1’i işler.

3-Burada Metot1’e int tipinden b değişkeni parametre olarak verilmiştir. int türü bildiğiniz gibi bir değer türü olduğundan derleyici b değişkeninin stack bölgesinde bir kopyasını oluşturur. (Bu kopyaya a ismini verdim)

4- Artık derleyici Metot1’i işlerken kopyaladığını bu a değişkenini kullanacaktır, nitekim Metot1’in geri dönüş değerinin hesaplandığı satıra geldiğinde bu a değişkeni 1 arttırılmıştır.

5- a değişkeni Main metodu içerisinde tanımlandığı şekilde c isimli değişkene aktarılmıştır.
Metot1 isimli metodun bitişinde ise kopyalanan a değişkeni artık kullanılmayacağından silinmiştir.

Evet görüldüğü gibi esas argümanımız olan b değişkeni herhangi bir değişime uğramamıştır.

2-Referansa Göre: Referans tipindeki bir argümanı bir metodun parametresine aktarırken, argümanın kopyası yerine argümanın adresini işaret eden bir referans gönderilir. Bu referansın aktarıldığı metotta değişmesi argümanın da değişmesine neden olacaktır. Aşağıdaki kodu inceleyelim:

class Sinif
{
public int a;
}
class ReferansTipiyleAktarma
{
static void Metot2(Sinif referans)
{
referans.a = 10;
}
static void Main()
{
Sinif nesne = new Sinif();
nesne.a = 5;
Metot1(nesne);
Console.WriteLine("nesne.a = {0}",nesne.a);
Console.ReadLine();
}
}

Ekran çıktısı:

nesne.a = 10;

metot_referans_tipi

Burada can alıcı nokta 4 numaralı kısımdır. Bu kısımda metodun parametresi referans tipinde olduğundan esas argüman olan nesne.a’nın adresini tutan referans.a referansı oluşturulmuştur. Şekilde de görüldüğü üzere referans.a ile nesne.a heap bölgesindeki aynı adresi göstermektedir. Metot2 içerisinde bu adresin 10 olarak değiştirilmesi esas argümanımız olan nesne.a değerinin de değişmesine neden olmuştur.

Peki biz bir değer tipini metodumuza referans tipi olarak atamak istersek ne yapmalıyız. İşte bu noktada ref ve out anahtar kelimeleri imdadımıza yetişiyor.

ref Kullanmak: Bazı durumlarda değer tipindeki esas argümanı değiştirmek isteyebiliriz. Bu durumda argümanımıza referans tipiymiş gibi davranılmasını sağlayan ref anahtar kelimesini kullanırız. Aşağıdaki kodu inceleyelim:

using System;
namespace RefOut
{
class refAnahtarKelimesi
{
static void Metot3(ref int a)
{
a += 10;
}
static void Main()
{
int a = 5;
Metot3(ref a);
Console.WriteLine("a = {0}",a);
Console.ReadLine();
}
}
}

Ekran çıktısı:

a = 15

Gördüğümüz gibi a değişkeninin 5 olan değeri Metot3 metodu çalıştırıldıktan sonra 15 olarak değişti. Burada dikkatinizi çekmek istediğim birkaç husus söz konusu. İlk olarak metodumuzu tanımlarken ref kullanarak bir parametre kullandıysak, metodumuzu kullanırken de aynı parametrenin önüne ref anahtar kelimesini koymalıyız. Örneğimizde Metot3(a) şeklinde bir kullanım bu yüzden hata verecektir. İkinci bir husus ise ref olan parametremize aktarılan değişkenin mutlaka ilk değerinin atanması gerekir. Örneğimizde a değişkenimizi tanımladıktan sonra 5 değerini atamamız derleyicinin hata vermesini engellemiştir.

out Kullanmak: Metodumuzdan return ile tek bir değer döndürebiliyorduk, fakat bir metottan birden fazla değer döndürmek isteyebiliriz. Bir önceki kapsamda gördüğümü ref anahtar kelimesi ile bunu yapmak mümkün olsa da, ref kullandığımızda ilk değer atama zorunluluğu gereksiz yere ilk değer atamamıza neden olacaktır. Aşağıdaki kodu inceleyelim:

using System;
namespace RefOut
{
class outAnahtarKelimesi
{
static double Metot4(double a, out double yari)
{
yari = a / 2;
return a * a;
}
static void Main()
{
double a = 10;
double Yarisi;
double kare = Metot4(a, out Yarisi);
Console.WriteLine("Kare = {0}", kare);
Console.WriteLine("Yarisi = {0}", Yarisi);
Console.ReadLine();
}
}
}

Ekran çıktısı:

Kare = 100
Yarisi = 5

Örnek çok kullanışlı olmasa da out kullanımını özetlemektedir. Metodumuz return anahtar kelimesi ile ilk parametrenin karesini döndürürken, out olarak tanımlı olan yari isimli parametre ise ilk parametrenin yarısını geriye döndürmektedir. Dikkat ederseniz double olarak tanımlanan Yarisi isimli değişkene ilk değer atanmamış olup, daha sonra bu değişkene değeri Metot4 atamıştır. Aslına bakarsanız out ile tanımlı bir parametrenin tanımlanma sebebi de budur. Yani out ile tanımlı bir parametreye, tanımlandığı metot sona ermeden önce ilgili metot tarafından değer atanır. Böylece metodumuz birden fazla değeri döndürmüş olur.
alıntı..: algoritma.org

Pin It on Pinterest