C# Fonksiyonlar, Şu ana kadar yaptığımız örneklerde alında farkında olmadan hazır bir fonksiyon olan ReadLine(), WriteLine() vb. gibi metotlar kullanıldı. Aslında bütün örneklerimizde birer c# fonksiyonu (diğer bir adı ise C# metodu) yaratmıştık. O da çalışabilir her programda bulunması gereken Main metoduydu. Artık Main metodu gibi başka metotlar yaratıp programımızın içinde kullanabileceğiz. Metotlar oluşturarak programımızı parçalara böler ve programımızın karmaşıklığını azaltırız. Ayrıca bazı kodları bir metot içine alıp aynı kodlara ihtiyacımız olduğunda bu metodu çağırabiliriz. Bu sayede de kod hamallığı yapmaktan kurtuluruz. Peki bir C# fonksiyonu nasıl oluşturulur?
1234int
MetotAdi(
int
a,
int
b)
{
return
a+b;
}
Bu metot, iki tane int türünden girdi alır ve bu girdilerin toplamını int türünden tutar. Ancak bu metodu programımız içinde kullanabilmemiz için bu metodun içinde bulunduğu sınıf türünden bir nesne yaratıp “.” operatörüyle bu nesne üzerinden metodumuz erişmeliyiz.
12345678910int
Topla(
int
a,
int
b)
{
return
a+b;
}
static
void
Main()
{
Metotlar nesne=
new
Metotlar();
int
a=nesne.Topla(2,5);
Console.Write(a);
}
static olarak tanımlanan metotlara erişmek için metodun içinde bulunduğu sınıf türünden bir nesne yaratmaya gerek yoktur. static metot olarak tanımlanan metotlara sadece metodun adını yazarak erişilebilir.
123456789static
int
Topla(
int
a,
int
b)
{
return
a+b;
}
static
void
Main()
{
int
a=Topla(2,5);
Console.Write(a);
}
– Bütün programlarda önce Main metodu çalışır. Diğer metotlar Main metodunun içinden çağrılmadıkça çalışmaz.
– Eğer metot, içinde bulunduğumuz sınıfta değil de, başka bir sınıf içinde yaratılmışsa o metodu kullanabilmek için önce sınıfı yazmamız gerekir.
1234567class
Metotlar1
{
public
static
int
Topla(
int
a,
int
b)
{
return
a + b;
}
}
12345678class
Metotlar2
{
static
void
Main()
{
int
a = Metotlar1.Topla(2, 5);
Console.Write(a);
}
}
Dikkat ettiyseniz bu metodun yaratılma satırının (4. satır) başına public anahtar sözcüğü konmuş. public sözcüğüyle derleyiciye bu metoda her sınıftan erişilebileceğini söylüyoruz. Eğer public sözcüğü yazılmamış olsaydı bu metoda sadece Metotlar1 sınıfından erişilebilirdi.
Şimdi de static olmayan bir metodu başka bir sınıf içinde yaratalım ve kullanalım:
1234567class
Metotlar1
{
public
int
Topla(
int
a,
int
b)
{
return
a + b;
}
}
123456789class
Metotlar2
{
static
void
Main()
{
Metotlar1 nesne =
new
Metotlar1();
int
a = nesne.Topla(3, 9);
Console.Write(a);
}
}
Herhangi bir değer tutmayan (WriteLine gibi) metotları void anahtar sözcüğüyle yaratırız.
1234567static
void
Yaz(
object
a,
int
b)
{
for
(; b > 0; b--)
Console.Write(a);}
static
void
Main()
{
Yaz(
"deneme"
, 5);
}
Herhangi bir değer tutmayan metotlarda return; komutu, yanına herhangi bir ifade olmadan kullanılabilir. Aslında return; komutunun asıl görevi metottan çıkmaktır, ancak yanına bazı ifadeler koyularak metodun tuttuğu değeri belirtme vazifesi de görür. Örneğin bir if koşulu yaratıp, eğer koşul sağlanırsa metottan çıkılmasını, koşul sağlanmazsa başka komutlar da çalıştırılmasını sağlayabiliriz. Ancak doğal olarak bir metodun son satırında return; komutunun kullanılması gereksizdir.
1234567891011static
void
Yaz(
object
a,
int
b)
{
if
(b > 10)
return
;
for
(; b > 0; b--)
Console.Write(a);
}
static
void
Main()
{
Yaz(
'n'
, 10);
}
Bu programda eğer metoda verilen ikinci parametre 10’dan büyükse metottan hiçbir şey yapılmadan çıkılıyor.
– C# Fonksiyonları kullanırken parametrelerini doğru sayıda, doğru sırada ve doğru türde vermeliyiz.
– Değer tutan metotlarda return satırıyla belirtilen ifade, metodu yaratırken verilen türle uyumlu olmalıdır.
– Değer tutmayan (void ile belirtilmiş) metotlarda return komutunun herhangi bir ifadeyle kullanılması yasaktır.
– Değer tutmayan C# metotları nın bir değermiş gibi kullanılması yasaktır.
– C# Metotları değer tutmayabileceği gibi, parametre de almayabilirler.
1234static
void
Yaz()
{
Console.Write(
"deneme"
);
}
1234static
void
Main()
{
Yaz();
}
Buradaki ekrana “deneme” yazan metot herhangi bir parametre almaz. Dolayısıyla da programda kullanırken de parantezlerin içine hiçbir şey yazılmaz.
Bir metodun içinde başka bir metot yaratılamaz. Örneğin aşağıdaki gibi bir kullanım hatalıdır.
12345678static
void
Yaz()
{
Console.Write(
"deneme"
);
static
void
Ciz()
{
Console.Write(
"\n"
);
}
}
1234static
void
Main()
{
Yaz();
}
C# Metodu yaratılırken ki metot parantezindeki değişkenlerin türleri tek tek belirtilmelidir. Virgül ile ortak tür belirtimi yapılamaz.
Yani,
1static
void
Ornek(
int
a,
int
b)
yerine
1static
void
Ornek(
int
a, b)
//yazılamaz.
C# fonksiyonlarına dizi gönderme yapılabildiği gibi bir C# fonksiyonu geriye dizi döndürme de sağlanabilir.
12345678910static
void
Yaz(
int
[] dizi)
{
foreach
(
int
i
in
dizi)
Console.WriteLine(i);
}
static
void
Main()
{
int
[] dizi = { 1, 2, 4, 7, 9 };
Yaz(dizi);
}
Buradaki Yaz metodu kendisine parametre olarak verilen dizinin elemanlarını alt alta yazdı. Eğer yalnızca int[] türündeki değil bütün türlerdeki dizileri ekrana yazan bir metot yazmak istiyorsak;
12345678910static
void
Yaz(Array dizi)
{
foreach
(
object
i
in
dizi)
Console.WriteLine(i);
}
static
void
Main()
{
int
[] dizi = { 1, 2, 4, 7, 9 };
Yaz(dizi);
}
Dizi ve değişken parametreler arasındaki fark içi aşağıdaki programların çıktılarını kontrol ediniz.
Dizi olarak parametre gönderilen bir metot.
12345678910111213141516static
void
Degistir(
int
[] dizi)
{
for
(
int
i = 0; i < 5; i++)
dizi[i] = 10;
}
static
void
Yaz(Array dizi)
{
foreach
(
object
a
in
dizi)
Console.WriteLine(a);
}
static
void
Main()
{
int
[] dizi = { 1, 2, 4, 7, 8 };
Degistir(dizi);
Yaz(dizi);
}
Değişken olarak parametre gönderilen bir metot.
1234567891011121314static
void
Degistir(
int
sayi)
{
sayi = 10;
}
static
void
Yaz(
int
sayi)
{
Console.WriteLine(sayi);
}
static
void
Main()
{
int
sayi = 1;
Degistir(sayi);
Yaz(sayi);
}
Bu iki programı çalıştırdığınızda göreceksiniz ki metoda parametre olarak aktarılan dizinin metot içinde bir elemanının değiştirilmesi esas diziyi etkiliyor. Ancak metoda parametre olarak aktarılan değişkenin metot içinde değiştirilmesi esas değişkeni etkilemiyor. Çünkü bir metoda parametre olarak bir dizi verildiğinde derleyici metoda dizinin bellekteki adresini verir; metot o adresteki verilerle çalışır. Dolayısıyla da dizinin herhangi bir elemanındaki değişiklik esas diziyi etkileyecektir. Çünkü gerek esas program, gerekse de metot aynı adresteki verilere erişir. Halbuki bir metoda parametre olarak bir değişken verdiğimizde metot için değişkenin bellekteki adresi önemli değildir, metot için önemli olan değişkenin değeridir. Metot, değişkeni kullanabilmek için geçici bir bellek bölgesi yaratır ve parametre olarak aldığı değişkenin değerini bu geçici bellek bölgesine kopyalar ve o geçici bellek bölgesiyle çalışır. Metottan çıkıldığında da o geçici bellek bölgesi silinir.
Peki bir metoda aktarılan bir değişkende yapılan bir değişikliğin tıpkı dizilerdeki gibi esas değişkeni etkilemesini ister miydiniz?
İşte bunun için C#’ın ref ve out olmak üzere iki anahtar sözcüğü vardır.
1234567891011121314static
void
Degistir(
ref
int
sayi)
{
sayi = 10;
}
static
void
Yaz(
int
sayi)
{
Console.WriteLine(sayi);
}
static
void
Main()
{
int
sayi = 1;
Degistir(
ref
sayi);
Yaz(sayi);
}
ref anahtar sözcüğü değişkenlerin metotlara adres gösterme yoluyla aktarılmasını sağlar. Gördüğünüz gibi ref sözcüğünün hem metodu çağırırken , hem de metodu yaratırken değişkenden önce yazılması gerekiyor. Bu program ekrana 10 yazacaktır. Ayrıca ref sözcüğüyle bir değişkenin metoda adres gösterme yoluyla aktarılabilmesi için esas programda değişkene bir ilk değer verilmelidir. Yoksa program hata verir.
Kullanımı ref anahtar sözcüğüyle tamamen aynıdır. Tek farkı out ile belirtilen değişkenlere esas programda bir ilk değer verilmesinin zorunlu olmamasıdır. Örneğin aşağıdaki kullanım tamamen doğrudur.
123456789101112131415static
void
Degistir(
out
int
sayi)
{
sayi = 10;
}
static
void
Yaz(
int
sayi)
{
Console.WriteLine(sayi);
}
static
void
Main()
{
int
sayi;
// ref de ilk değer verilmesi gerekir.
Degistir(
out
sayi);
Yaz(sayi);
}
ref sözcüğünün dizilerle kullanımı gereksiz olmasına rağmen C# bunu kısıtlamamıştır. Ancak out sözcüğü dizilerle kullanılamaz.
C#’ta parametre sayısı ve/veya parametrelerin türleri farklı olmak şartıyla aynı isimli birden fazla metot yaratılabilir. Buna metotların aşırı yüklenmesi denir.
C#, bir metot çağrıldığında ve çağrılan metot aynı isimli birden fazla metot bulunduğunda metodun çağrılış biçimine bakar. Yani ana programdaki metoda girilen parametrelerle yaratılmış olan metotların parametrelerini kıyaslar. Önce parametre sayısına bakar. Eğer aynı isimli ve aynı sayıda parametreli birden fazla metot varsa bu sefer parametre türlerinde tam uyumluluk arar, parametre türlerinin tam uyumlu olduğu bir metot bulamazsa bilinçsiz tür dönüşümünün mümkün olduğu bir metot arar, onu da bulamazsa programımız hata verir.
123456789101112131415161718static
void
Metot1(
int
x,
int
y)
{
Console.WriteLine(
"1. metot çağrıldı."
);
}
static
void
Metot1(
float
x,
float
y)
{
Console.WriteLine(
"2. metot çağrıldı."
);
}
static
void
Metot1(
string
x,
string
y)
{
Console.WriteLine(
"3. metot çağrıldı."
);
}
static
void
Main()
{
Metot1(
"deneme"
,
"deneme"
);
Metot1(5, 6);
Metot1(10f, 56f);
}
Bu programda üç metot da aynı sayıda parametre almış. Bu durumda parametrelerin türlerine bakılır. Ana programdaki Metot1(“deneme”,”deneme”); satırıyla üçüncü metot çağrılır. Metot1(5,6); metot çağrımının parametre türlerinin tam uyumlu olduğu metot birinci metottur, o yüzden birinci metot çağrılır. Eğer birinci metot yaratılmamış olsaydı ikinci metot çağrılacaktı. Son olarak Metot1(10f,56f); satırıyla da ikinci metot çağrılır.
123456789101112static
void
Metot1(
float
x,
float
y)
{
Console.WriteLine(
"1. metot çağrıldı."
);
}
static
void
Metot1(
double
x,
double
y)
{
Console.WriteLine(
"2. metot çağrıldı."
);
}
static
void
Main()
{
Metot1(5, 6);
}
Yukarıdaki programda iki metodun da parametre sayısı eşit, iki metotta da tam tür uyumu yok ve iki metotta da bilinçsiz tür dönüşümü mümkün. Bu durumda en az kapasiteli türlü metot çağrılır. Yani bu programda birinci metot çağrılır.
123456789101112static
void
Metot1(
float
x,
float
y)
{
Console.WriteLine(
"1. metot çağrıldı."
);
}
static
void
Metot1(
int
x,
int
y)
{
Console.WriteLine(
"2. metot çağrıldı."
);
}
static
void
Main()
{
Metot1(5, 6.4f);
}
Bu durumda birinci metot çağrılır.
123456789101112static
void
Metot1(
float
x,
float
y)
{
Console.WriteLine(
"1. metot çağrıldı."
);
}
static
void
Metot1(
int
x,
int
y)
{
Console.WriteLine(
"2. metot çağrıldı."
);
}
static
void
Main()
{
Metot1(
'f'
,
'g'
);
}
Bu durumda ikinci metot çağrılır. Çünkü char hem inte hem de floata bilinçsiz olarak dönüşebilir. Ancak int daha az kapasitelidir.
Şimdiye kadar metotlarımıza gönderdiğimiz parametre sayısı belliydi ve bu parametre sayısından farklı bir miktarda parametre girersek programımız hata veriyordu. Artık istediğimiz sayıda parametre girebileceğimiz metotlar yapmasını göreceğiz.
1234567891011121314151617static
int
Toplam(
params
int
[] sayilar)
{
if
(sayilar.Length == 0)
return
0;
int
toplam = 0;
foreach
(
int
i
in
sayilar)
toplam += i;
return
toplam;
}
static
void
Main()
{
Console.WriteLine(Toplam());
Console.WriteLine(Toplam(5));
Console.WriteLine(Toplam(5, 10));
Console.WriteLine(Toplam(2, 9, 12));
Console.WriteLine(Toplam(7, 12, 45));
Console.Write(Toplam(123,12,5,7,9,4,12));}
Burada aldığı parametrelerin toplamını tutan bir C# metodu yazdık. Eğer metoda hiç parametre girilmemiş ise 0 değerini döndürmektedir.
Gördüğünüz gibi C# fonksiyonlar’ ında params anahtar sözcüğüyle girilen tüm parametreleri int[] türündeki sayilar dizisine aktardık ve bu diziyi metotta gönlümüzce kullandık. Bir de bu programımızda Length özelliğini gördünüz. Özellikler metotlara benzerler, metotlardan tek farkları “()” kısımları olmamasıdır. Dolayısıyla parametre almazlar. Örneğimizde sayilar. Length satırı sayilar dizisinin eleman sayısını int türünden tutar.
12345678910111213141516171819202122232425262728static
int
Islem(
string
a,
params
int
[] sayilar)
{
if
(a ==
"carp"
)
{
if
(sayilar.Length == 0)
return
1;
int
carpim = 1;
foreach
(
int
i
in
sayilar)
carpim *= i;
return
carpim;
}
else
if
(a ==
"topla"
)
{
if
(sayilar.Length == 0)
return
0;
int
toplam = 0;
foreach
(
int
i
in
sayilar)
toplam += i;
return
toplam;
}
else
return
0;
}
static
void
Main()
{
Console.WriteLine(Islem(
"topla"
,3,4,7,8));
Console.WriteLine(Islem(
"carp"
, 5,23,6));
}
Bu programdaki gibi metodumuzda değişken parametre yanında bir ya da daha fazla normal sabit parametre de olabilir. Ancak değişken parametre mutlaka en sonda yazılmalıdır.
Değer döndüren metotlarımız mutlaka her durumda değer döndürmelidir. Örneğin metodumuzda sondaki else kullanılmazsa programımız derlenmez. Çünkü else’i kullanmasaydık birinci parametre yalnızca “carp” veya “topla” olduğunda metodumuz bir değer döndürecekti. Ve bu da C# kurallarına aykırı.
C# fonksiyonlar ÖRNEK – 1
Parametresi ve deri dönüş değeri olmayan ekrana Merhaba yazan MerhabaYaz isminde metodu tanımlayınız.
C# fonksiyonlar ÖRNEK – 2
Gönderilen iki sayıdan büyük olanı geri gönderen metodu oluşturunuz.
C# fonksiyonlar ÖRNEK – 3
Girilen sayının tekmi çiftmi olduğunu bulduran programI metot kullanarak yazınız.
ÖRNEK – 1 ÇÖZÜMÜ
1234static
void
MerhabaYaz(){
Console.WriteLine(
"Merhaba"
);}
static
void
Main(
string
[] args){ MerhabaYaz();
Console.ReadKey();}
ÖRNEK – 2 ÇÖZÜMÜ
1234567891011121314151617private
static
int
BUYUK(
int
sayi1,
int
sayi2){
if
(sayi1 > sayi2)
return
sayi1;
else
if
(sayi2 > sayi1)
return
sayi2;
else
return
sayi1;
}
static
void
Main(
string
[] args)
{
Console.Write(
"Bir sayı giriniz"
);
int
s1 =
int
.Parse(Console.ReadLine());
Console.Write(
"Bir sayı daha giriniz"
);
int
s2 =
int
.Parse(Console.ReadLine());
Console.Write(BUYUK(s1, s2));
Console.ReadKey();
}
ÖRNEK – 3 ÇÖZÜMÜ
123456789101112131415161718192021static
bool
tekcift(
int
sayi)
{
bool
durum;
if
(sayi % 2 == 0)
durum =
true
;
else
durum =
false
;
return
durum;
}
static
void
Main(
string
[] args)
{
int
s1;
bool
drm;
Console.Write(
"Sayıyı Giriniz..:"
);
s1 = Convert.ToInt32(Console.ReadLine());
drm = tekcift(s1);
if
(drm ==
true
)
Console.Write(
"Sayı Çift"
);
else
Console.Write(
"Sayı Tek"
);
Console.ReadKey();}
Evet değerli arkadaşlar böylece C# fonksiyonlar başlıklı bir yazımızın daha sonu gelmiş olduk. Unutmayınız ki C# Fonksiyonlar konusu programlamanın en temel konularından birini oluşturmaktadır. Bu konuya hakimiyetiniz sizlerin bir çok noktada fazladan kod yazma zahmetinden kurtaracaktır. C# dersleri ile hakkında aklına takılanları yazmaktan çekinmeyin.
Dilerseniz bir önceki yazımız olan C# Diziler konusuna bir göz atabilirsiniz.
Web site tasarımı, web tabanlı yazılım ve kurumsal yazılım çözümleri ile Kodyaz.NET olarak yaptığımız her projede size %100 memnuniyet sözü veriyoruz. Kodyaz.NET olarak yaptığımız her projenin daima arkasındayız.
©2004 - 2019 Kodyaz.NET. Tüm hakları saklıdır. Kodyaz.NET Web Sitesi ve Web Tabanlı Yazılım Çözümleri