Makale Özeti

Bu makalemde c#'da metodlar ve aşırıyükleme kavramlarından bahsedeceğim.

Makale

Tüm yazılımcı arkadaşlara selamlar,

Bu makalemde Csharp metodlarından ve aşırı yükleme konularından bahsedeceğim.

Metod 
Bir objenin veya sınıfın belli işlemleri/hesaplamaları gerçekleştirmesi için kullandığı bir üyedir.

Yazım kuralı aşağıdaki gibidir.

Syntax 
Attributes(opt) Method-Modifiers(opt) Return-Type Member-Name (Parameter-List(opt))
Özellikler(opsiyonel) Erişim-Belirleyiciler(opsiyonel) Geri-Dönüş-Tipi Üye-İsmi (Parametre-Listesi(opsiyonel))

Attributes (Özellikler): Opsiyoneldir.Metodun özellik bilgilerini içerir.Bu konu hakkında ilerleyen zamanlarda ayrı bir makale yazacağım.

Method-Modifiers (Erişim Belirleyiciler): Opsiyoneldir.Metodun tipini amacını belirlerler.
Seçenekler: new - public - protected - internal - private - static - virtual - sealed - override - abstract - extern

Return Type (Geri Dönüş Tipi): Gereklidir.Metodun geri dönüş tipini belirler.Bu ya bir tür(string bool) olabilir ya da void olacaktır.

Member Name (Üye İsmi): Gereklidir.Metodun ismini belirler.

Parameter List (Parametre listesi): Opsiyoneldir.Metod'a gönderilecek değişkenlerin türlerini ve hafızada oluşturma biçimlerinin belirlendiği yerdir.

Metod tanımlama ile ilgili bazı kurallar mevcuttur.Bunlar;

Programımızın başlangıç noktası olan Main metodunu ikinci kez kullanamayız.
Metod isimleri nümerik karakter ile başlayamaz.
Metod ismi büyük küçük harf duyarlıdır.
Metod isimlerinde boşluk kullanılamaz.
Metodun geri dönüş değeri yoksa void anahtar sözcüğü kullanılmalıdır.
Metodların parametre bilgisi eksiksiz girilmelidir.
Bir metod bloğu içinde başka bir metod tanımı yapılamaz.
Metodun geri dönüş değeri ile return anahtar sözcüğü ile döndürülen tür aynı olmalıdır.

Bütün bu açıklamalardan sonra bir örnek vererek devam edelim.

Metod Örnekler
private void ÖrnekMetod()
{
    Console.Writeline("Bu metod mevcut kod bloğu içinde erişilebilirdir ve geri dönüş tipi void dir.");
}

public void ÖrnekMetod1()
{
    Console.Writeline("Bu metod hem mevcut kod bloğu içinden hem de bağlı sıfın oluşturulduğu ortamdan erişilebilir ve geri dönüş tipi void dir.");
}

private bool ÖrnekMetod2()
{
    Console.Writeline("Bu metod kod bloğu içinden erişilebilir ve geri dönüş tipi bool(true/false) dir.");
}

private int ÖrnekMetod3(string strDegisken)
{
    Console.Writeline("Bu metod kod bloğu içinden erişilebilir ve geri dönüş tipi int dir.Parametre olarak string bir değişken alır.");
}

İsterseniz şimdi biraz "method modifiers" lardan bahsedelim.Burda sadece iki modifierler hakkında bilgi vereceğim.Diğerlerini ilerleyen makalelerde göreceğiz.

Private: Metodun tanımlandığı sınıf içinde erişilebilir.
Public: Hem metodun tanımlandığı sınıf içinde hem de metodun bağlı olduğu sınıfın tanımlandığı ortamdan erişilebilir.
(Eğer herhangi bir method modifier belirtilmezse, metod bulunduğu blok içinde erişilebilir (private) olur)

Erişim alanlarını daha iyi anlamak için aşağıdaki resme bakabilirsiniz.

Burda iki sınıfımız mevcuttur.Class1 ve Class2 
Class1 'in üyeleri OrnekMetod ve OrnekMetod1
Class2'nin üyeleri gene OrnekMetod ve OrnekMetod1 dir.
Burda fark class2 sınıfının b ir public metodunun olmasıdır.

Bu kodu kendi geliştirme ortamınıza aktarın.
Kırmızı diktörtgen ile işaretlenmiş satırda c2 yazıp . (nokta)'ya bastığınızda intellisense
size c2 sınıfının üyelerini getirecektir.Bunlar arasında sadece OrnekMetod1 gözükecek OrnekMetod gozukmeyecektir.
Bunun sebebi iki metodun erişim belirleyicilerinde gizlidir.Public olarak tanımlanan metod dışardaki bir ortamdan erişilebilmektedir.

Bunun yanısıra Class1 bloğunda mavi dikdörtgen ile işaretlenmiş koda baktığınızda private olan OrnekMetod metoduna Class1 içinden erişebiliyoruz.

Şimdi isterseniz parametrelerden bahsedelim.Bazen yazacağımız metodlara yapacağımız işlemlerle ilgili değerler göndermemiz gerekir.Bunun için public değişkenleri kullanmamız yapı açısından ters olacak, gereksiz kaynak tüketimine sebep olacaktır.İşte bu tür durumlarda parametreler devreye girer.
Metodlar bir veya birden fazla değişik türden parametre alabilirler.Gerçek hayattan bir örnek vermemiz gerekirse bir matematik işlemi için bir sınıf tasarladığımızı ve bu sınıfın "Topla" isminde bir metodu olduğunu düşünürsek, toplanacak iki sayının bu metoda parametre olarak gönderilmesi iyi bir örnek olacaktır.

Örneği inceleyelim.

using System;

namespace MatematikIslemlerimiz
{
    class Class1
    {
        static void Main(string[] args)
        {
            MatematikIslemleri Mat=new MatematikIslemleri();
            Console.WriteLine("5+6=" + Mat.Topla(5,6).ToString() );
            Console.WriteLine("5-6=" + Mat.Cikar(5,6).ToString() );
            Console.WriteLine("5*6=" + Mat.Carp(5,6).ToString() );
            Console.WriteLine("5/6=" + Mat.Bol(5,6).ToString() );
        }
    }
    class MatematikIslemleri
    {
        public MatematikIslemleri()
        {}
        public int Topla(int intDeger1,int intDeger2)
        {
            return intDeger1+intDeger2;
        }
        public int Cikar(int intDeger1,int intDeger2)
        {
            return intDeger1-intDeger2;
        }
        public int Carp(int intDeger1,int intDeger2)
        {
            return intDeger1*intDeger2;
        }
        public int Bol(int intDeger1,int intDeger2)
        {
            return intDeger1/intDeger2;
        }
    }
}

Görmüş olduğunuz üzere Matematik işlemleri için yazmış olduğumuz metodlar int türünden parametreler almaktadır ve bu değişkenlerin ömürleri metod bloğu ile sınırlıdır.

Parametrelerin ref ve out anahtar sözcükleri ile işaretleyerek hafızada ne şekilde konumlanacağını ayarlayabiliriz.

using System;
namespace MatematikIslemlerimiz
{
    class Class1
    {
        static int intA=1;
        static void Main(string[] args)
        {
            Console.WriteLine("İşlem başlangıcı değer = " + intA);
            for (int intR=0;intR<10;intR++)
            {
                Arttir(ref intA );
            }
            Console.WriteLine("İşlem sonucu değer = " + intA);
        }
        static void Arttir(ref int intArttir)
        {
            intArttir+=intArttir;
        }
    }
}

Örnekte gördüğünüz gibi ref anahtar sözcüğü ile metoda değerin hafızada bulunduğu adres gönderilmekte ve bu sayede değer üzerinde yapılacak değişiklikler direkt olarak dış bloğa da yansımaktadır.

ref ve out arasındaki fark ise obje türünden değişken bildirimlerinde ref kullanılırsa objenin yaratılmış olması gerekmektedir out ta ise bu zorunluluk yoktur.
 

Peki, eğer metoda göndereceğimiz parametrelerin sayısı belli değilse?Mesela Topla metodu 2 adet int türünden parametre almaktadır.Eğer biz 3 sayıyı toplamak istersek ne yapacağız.
İşte bu tür durumlarda metoda parametre olarak dizi göndermemiz iyi bir çözüm olacaktır.

public int Topla(params int[] intDegerler)
{
    int intToplam=0;
    foreach (int intDeger in intDegerler)
    {
        intToplam+=intDeger;
    }
    return intToplam;
}

Bu yöntemi kullanarak artık Topla metoduna değişken sayıda parametre gönderebiliriz.

Overloading de nedir?
Gelelim beklenen konuya.Overloading (Aşırı yükleme)
Nedir bu overloading? Bazı tasarımlarda  bir metod'un alacağı parametre türü ve sayısı değişebilir.Çoğunuz peki neden params'ı kullanmıyoruz diyebilir.
Eğer değişik türden parametreler kullanmayacak olsaydık params uygun bir çözüm olacaktır.Fakat int double bool string türlerini aynı anda kullanamayız.
Bunun için c# overloading karamını desteklemektedir.

Bir önceki örneğimizde Topla metodu nu ele alalım.Parametre int türünden.Mevcut senaryoda double türünden iki değişkeni toplamak istediğimizde mevcut metod yetersiz kalacaktır.İşte bu tür durumlarda Topla metodunu aşağıdaki gibi aşırı yüklüyoruz.

public int Topla(int intDeger1,int intDeger2)
{
    return intDeger1+intDeger2;
}
public double Topla(double dblDeger1,double dblDeger2)
{
    return dblDeger1+dblDeger2;
}

Farkındaysanız metod kurallarında aynı isimli iki metodun kullanılamayacağından bahsetmiştik.Peki nasıl oldu da derleyici bu kodda hata vermedi?
C# metodların bütünlüğünü kontrol ederken her metod için bir imza yaratır.Bu imza yaratılırken metodun ismi, aldığı parametreler kullanılır.Metodun geri dönüş değeri ve params ile işaretlenmiş parametreler imza'ya dahil edilmezler.


Aşağıdaki örneği inceleyelim.

Görüldüğü gibi metodların isimleri aynı fakat imzaları farklı olduğu için c# bu metodun aşırı yüklendiğini kabul edecektir. 
c#'da topla metodunu çağırdığımızda intellisense özelliği devreye girecek ve bize overload edilmiş metodun alabileceği parametre kombinasyonlarını sıralayacaktır.



Evet bir makalenin daha sonuna geldik.Biraz uzun oldu ama umarım yararlı olmuştur.
Hepinize mutlu günler dilerim. 

Levent YILDIZ
Gulf Agency Company - TURKEY
IT Manager
MCP
msmoracle@hotmail.com 
levent.yildiz@gacworld.com 
http://www.gacworld.com