| 
      
        |  SİTE 
            İÇİ ARAMA |  
        |  |  
      
        |  Blogroll |  
        |  |    | 
        
            |  |  
            | 
                    
                        | Detayları ile Operatörleri Aşırı Yüklemek (Operator Overloading) |  |  
                        | 
	
    
		
            | Gönderiliyor lütfen bekleyin... | 
 |  |  
            | Hepimizin  bildiği gibi operatörler, tipler arasında çeşitli işlemler yapan  işaretlerdir.Aritmetik Operatörler,Mantıksal Operatörler gibi kendi aralarında  gruplara ayrılmışlardır.Aritmetik operatörlerden konuşmak gerekirse; “+”  operatörünün varsayılan davranışı verilen iki değerin aritmetik toplamını  almaktır.Mantıksal operatörlerden bir örnek vermek gerekirse; “<”  operatörünün varsayılan görevi işaretin sol tarafındaki değerin sağ tarafındaki  değere göre küçük olup olmadığını denetlemektir. 
 
 
      Sayısal ifadeler için “+” aritmetik  operatörünün üstlendiği görev toplama işlemi yapmak iken, DateTime ve TimeSpan  ifadelerde bu görev tamamen farklı bir hal alır.
        | //+ operatörünün int tipi için  üstlendiği eylem. int a = 10;
 int b = 50;
 int c = a  + b; // c nin değeri 60’dır.
 |  
 
 
      Yukarıda da görüldüğü üzere +  operatörünün davranışı int tipler için farklı, DateTime tipler için farklıdır. DateTime  yapısı(struct) içinde + operatörüne yeni bir davranış biçimi olan tarihle, tarih  farkını birleştirme görevi aşırı yüklenmiştir(overload).
        | // + operatörünün DateTime tipi  için üstlendiği eylem. DateTime dt = new DateTime(2007,  12, 12);
 DateTime dt1 = new DateTime(2006,  12, 12);
 TimeSpan ts = dt -  dt1;
 DateTime top = dt +  ts;
 Console.WriteLine(top);
 |  
 
  
 
  
 //DateTime struct’ının metadatasında görülen operatör aşırı yükleme  (operator overloading)
    
    
    
    Bizde eğer operatörlerle  kullanılabilir tipler yazmak istersek(class veya struct); bu tiplere  operatörlerle kullanıldıklarında yapacakları işi ögretmemiz yani operatörleri  aşırı yüklememiz (operatör overloading) gerekmektedir. Örnek bir senaryo üzerinden hareket  edelim. Söz gelimi bir firma sahibi, kasiyerlerinin toplam ne kadar ürün  sattığını öğrenmek istiyor olsun. Bunun için işe Kasiyer isimli bir  sınıfı(class) oluşturarak başlayalım.
 
 
 
      Kasiyer sınıfımızı(class)  oluşturduk. Şimdide gelin sınıfımızı örnekledikten sonra kullanacak olan  program.cs dosyasını aşağıdaki kod parçasında olduğu gibi oluşturalım.
        | using System; using System.Collections.Generic;
 using System.Text;
 
 namespace OperatörOverloading
 {
 class Kasiyer
 {
 //iki adet field tanımlayalım.
 int _satisAdet;
 string _calisanAdi;
 //yapıcı metotumuzda (constructor) 
		degerlerini sınıfı kullanan kullanıcıdan alalım.
 public Kasiyer(string calisanAdi,int 
		sattigiUrunAdet)
 {
 _calisanAdi = 
		calisanAdi;
 _satisAdet = 
		sattigiUrunAdet;
 }
 //ve bilgi almak istedigimizde bize 
		yardımcı olması adına object sınıfının virtual olarak isaretlenmis 
		ToString() metotunu (override) ezelim.
 public override string ToString()
 {
 return 
		string.Format("{0} {1} adet satis",_calisanAdi,_satisAdet);
 }
 }
 }
 |  
 
 
      Oluşturduğumuz  kasiyer tipinden nesne örneklerini (ksyrHasan,ksyrAyten) herhangi bir operatörle  kullanmaya çalıştığımız taktirde bu iki tipi bu operatörle kullanamayacağımızı  belirten bir hata mesajını derleme zamanında alırız. Bunun sebebi kullandığımız  operatörün bu iki tiple kullanıldığında ne gibi bir eylemde bulunacağını  bilmemesinden kaynaklanmaktadır. 
	Toplama  operatörünün Kasiyer nesne örnekleri üzerinde kullanılmasını sağlamak için  gelin bu operatörü aşırı yükleyelim ve artık ne iş yapacağını bilsin!.
        | using System; using System.Collections.Generic;
 using System.Text;
 
 namespace OperatörOverloading
 {
 class Program
 {
 static void Main(string[] args)
 {
 Console.WriteLine("***Operatörleri Aşırı Yükleyelim***\n");
 //ksyr 
		sınıfından iki farklı nesne olusturduk.Satis degerlerini 30 ve 35 olarak 
		belirledik.
 Kasiyer 
		ksyrHasan = new Kasiyer("Hasan", 30);
 Kasiyer 
		ksyrAyten = new Kasiyer("Ayten", 35);
 Console.WriteLine(ksyrAyten.ToString());
 Console.WriteLine(ksyrHasan);
 //Error 1 
		Operatör ’+’ cannot be applied to operands of type 
		’OperatörOverloading.Kasiyer’ and ’OperatörOverloading.Kasiyer’ 
		D:\Work\testing\OperatörOverloading\OperatörOverloading\Program.cs 36 42 
		OperatörOverloading
 Kasiyer 
		ksyrlerToplamSatis = ksyrHasan + ksyrAyten;
 }
 }
 }
 |  
 Yapılan  son güncellemeden sonra Kasiyer Sınıfı:
 
 
 
      Operatörleri overload ederken bir takım kısıtlamalar  vardır. Şimdi biraz bunlardan bahsedelim.
        | using System; using System.Collections.Generic;
 using System.Text;
 
 namespace OperatörOverloading
 {
 class Kasiyer
 {
 //iki adet field tanımlayalım.
 int _satisAdet;
 string _calisanAdi;
 //yapıcı metotumuzda (constructior) 
		degerlerini sınıfı kullanan kullanıcıdan alalım.
 public Kasiyer(string calisanAdi,int 
		sattigiUrunAdet)
 {
 _calisanAdi = 
		calisanAdi;
 _satisAdet = 
		sattigiUrunAdet;
 }
 //ve bilgi almak istedigimizde bize 
		yardımcı olması adına object sınıfının virtual olarak isaretlenmis 
		ToString() metotunu (override) ezelim.
 public override string ToString()
 {
 return 
		string.Format("{0} {1} adet satis",_calisanAdi,_satisAdet);
 }
 //En az bir Parametre Sınıf tipinden 
		olmalı.
 public static Kasiyer operator 
		+(Kasiyer ks1,Kasiyer ks2)
 {
 int 
		toplamSatis = ks1._satisAdet + ks2._satisAdet;
 return new 
		Kasiyer("toplam", toplamSatis);
 }
 }
 }
 |  
 
 
      “Operatör Overload metotlarıda”, overload edilebilir. Operatör,"Kasiyer+tip" şeklinde kullanıldığında tip alanı için gelecek tipe göre en uygun  metotu tercih edecektir.(Pointy  geliştirici tarafından yazılmış örnek bir sınıftır)Operatör overload metotlarında       erişim belirleyicisi olarak sadece public kullanılmalıdır. Sınıfın nesne       örnekleri heryerde operatörlerle kullanılmak istenebilir. Bu yüzden de       mantıklı olanı public olmasıdır.Operatör overload metotlarda niteleyici       mutlaka static olmalıdır. Static olmasının sebebi metotun çağrılabilmesi       (invoke) için herhangi bir nesne örneğine ihtiyacının olmaması  ve nesne örneklerinden nesne örneklerine       yapılacak işlemin değişmemesidir. Yani toplama işlemini nasıl yapacağını       bir kere öğrenmesi yeterlidir. Her nesne örneğinde tekrar öğrenmesine       gerek yoktur. (Bkz : “Statik Olmak” ).Operatör overload metotlarda parametre       sayısı iki adet olmalıdır (bilinçli/bilinçsiz atama operatörleri hariç) ve       bunlardan bir tanesi mutlaka operatörü overload ettiğimiz sınıf tipinden       olmalıdır.(diğer parametre sistemde tanımlı tiplerden birisi yada kendi       yazdığımız tiplerden birisi olabilir.)Geri dönüş tipi iş mantığımıza       göre herhangi anlamlı bir tip olabilir. Örnek senaryoda kasiyerlerin       sattıkları ürün toplamlarını taşıyan yeni bir Kasiyer sınıfı nesne örneği       geriye döndürülmektedir. Elbetteki istenirse uygun ve anlamlı olan başka       tiplerde dönüş değeri olarak göz önüne alınabilir. 
 
 
      
        | public static Kasiyer operatör +(Kasiyer 
		ks1,Kasiyer ks2) {
 int toplamSatis = ks1._satisAdet + ks2._satisAdet;
 return new Kasiyer("toplam", toplamSatis);
 }
 public static Kasiyer operatör +(Kasiyer ks1, Pointy p)
 {
 int toplamSatis = ks1._satisAdet + p.x;
 return new Kasiyer("toplam", toplamSatis);
 }
 public static int operator +(Kasiyer ks1, int a)
 {
 int toplamSatis = ks1._satisAdet + a;
 return toplamSatis;
 }
 |  
 
      Program.cs dosyamıza geri dönelim ve uygulamamızı tekrar  çalıştırmayı deneyelim.
        |  | Operatör Overload metotların geri dönüş tipi void  olamaz! |  
 
 
      
        | using System; using System.Collections.Generic;
 using System.Text;
 
 namespace OperatörOverloading
 {
 class Program
 {
 static void Main(string[] args)
 {
 Console.WriteLine("***Operatörleri Aşırı Yükleyelim***\n");
 //ksyr 
		sınıfından iki farklı nesne olusturduk.Satis degerlerini 30 ve 35 olarak 
		belirledik.
 Kasiyer 
		ksyrHasan = new Kasiyer("Hasan", 30);
 Kasiyer 
		ksyrAyten = new Kasiyer("Ayten", 35);
 Console.WriteLine(ksyrAyten.ToString());
 Console.WriteLine(ksyrHasan);
 Kasiyer 
		ksyrlerToplamSatis = ksyrHasan + ksyrAyten;
 //To.String() 
		metotunu Kasiyer sınıfında override ettigimiz için Console.WriteLine 
		override metot içindeki string ifadeyi yazacaktır.
 //son duruma 
		bakalım?
 Console.WriteLine(ksyrlerToplamSatis);
 }
 }
 }
 
 
 |   
 Hiçbir  derleme zamanı hatası almadık. Çünkü Kasiyer sınıfı nesne örnekleri ile  birlikte kullandığımız operatör artık bu nesne örnekleri ile kullanıldığında ne  gibi bir işlem yapacağını Kasiyer sınıfı içerisinde tanımlanan, operatör +  anahtar sözcüklerini yapısında barındıran metot sayesinde bilmektedir.
 
 
 
 
 
 
      
        |  | Kasiyer ksyrlerToplamSatis = ksyrHasan +  ksyrAyten; 
 Satırında aslında arka tarafta 
		 bilinçsiz (implicitly) olarak gizlice
 
 Kasiyer ksyrlerToplamSatis= Kasiyer.operatör +( ksyrHasan,ksyrAyten); şeklinde  metot çagrımı yapılmaktadır.
 
 
 |  
 AŞIRI YÜKLENEBİLİR  OPERATÖRLER (OVERLOADABLE OPERATORS)
 
 
 
 
      
        | C# Operatör 
 
 | Yükelenebilite 
 
 |  
        | +, –, !, ~, ++, – –, true, false 
 
 | Aşırı    yüklenebilirler. 
 
 |  
        | +, –, *, /, %, &, |, ^,    <<, >> 
 
 | Aşırı    yüklenebilirler. 
 
 |  
        | ==, !=, <, >, <=, >= 
 
 | Aşırı    yüklenebilirler. 
 
 |  
        | [] 
 
 | Aşırı    yüklenemez.(indexer sayesinde fonksiyonalite kazanabilir) 
 
 |  
        | () 
 
 | Aşırı    yüklenemez. 
 
 |  
        | +=, -=, *=, /=, %=, &=, |=,    ^=, <<=, >>= 
 
 | Binary ve    Aritmetik operatörlerle kullanılan atama operatörleri binary veya aritmetik operatörler    aşırı yüklendiği taktirde kullanılabilirler. 
 
 |  
 
      Diğer operatörlerede  şöyle bir bakalım;Mantıksal operatörleri tek başına aşırı yükeleyemeyiz. Çift  olarak ele almamız gerekir. Eğer ==,<,<= operatörlerinden birini aşırı  yüklemek istersek !=,>,>= operatörlerinden ilgili operatörüde aşırı  yüklememiz gerekir.
        |  | Binary ve Aritmetik operatörlerle kullanılan atama  operatörleri (+=, -=, *=, /=, %=, &=, |=, ^=, <<=,  >>=), binary ve aritmetik operatörler aşırı yüklendiğinde  kullanılabilirler. 
 
            
              | ksyrHasan    += ksyrAyten; Console.WriteLine(ksyrHasan);
 |  |  
 Mantıksal  operatörler bool değer döndürecek şekilde aşırı yüklenirler. Zaten mantıklı  olanda budur. Fakat diğer tipleri döndürme konusunda herhangi bir kısıtlama  getirilmemiştir.
 
 
 
	
		| public static bool operator <(Kasiyer k1, Kasiyer k2) {
 //kod bloğu
 }
 
 
 |  Mantıksal  operatörler aşırı yüklenirken işleri kolaylaştırmak için bir takım metotlardan  faydalanabiliriz. Bunlardan == ve != için konuşmak gerekirse object sınıfının  virtual olarak işaretlenmiş Equals metodunu override etmek bu operatörleri  aşırı yüklerken oldukça işimize yarayacaktır.
 
 
 
 
 
 
 
      Şimdi de “>” ve “<” operatörlerine bakalım. Bu operatörleri aşırı yüklemede bize yardımcı olması için IComparable veya .Net 2.0 la birlikte gelen generic IComparable<> arayüzünü uyarlayabiliriz (Interface Implementation).
        | public override bool Equals(object obj) {
 Kasiyer k1 =  (Kasiyer)obj;
 if (k1._calisanAdi == this._calisanAdi &&  k1._satisAdet==this._satisAdet)
 {
 return true;
 }
 return false;
 }
 public static bool operator ==(Kasiyer k1, Kasiyer k2)
 {
 return k1.Equals(k2);
 }
 public static bool operator !=(Kasiyer k1, Kasiyer k2)
 {
 return !(k1.Equals(k2));
 }
 |  
 
 
      IComparable<> generic interface’ini implement edip CompareTo metotunu kodladıktan sonra artık “<” ve “>” operatörlerini aşırı yüklemek için artık ekstra efor sarfetmemiz gerekmiyor. İlk operatör overloading metot için konusmak gerekirse;k1.CompareTo(k2) ifadesinden eger k1 küçükse -1 donecektir. ifadenin sağında  ise < 0 bulunmaktadır ve k1’in küçük olma durumunda dönecek değer true olacaktır. Acaba overload edilen operatörlerimiz CIL kodunda nasıl yer alıyor. Visual Studio Command Promt vasıtasıyla ildasm.exe aracımızı açıp uygulamamızın CIL kodunu inceleyelim şimdide.
        | using System; using System.Collections.Generic;
 using System.Text;
 
 namespace OperatörOverloading
 {
 class Kasiyer:IComparable<Kasiyer>
 {
 #region IComparable<Kasiyer> Members
 //CompareTo metotu 
		nesneAdi.CompareTo(karsilastirilacakNesne) seklinde kullanılır.Eger 
		nesneAdi karsilastirilacak nesneden büyükse 1,küçükse -1,eşitse 0         
		dondurur.
 public int CompareTo(Kasiyer other)
 {
 if 
		(this._satisAdet > other._satisAdet)
 {
 return 1;
 }
 else if 
		(this._satisAdet < other._satisAdet)
 {
 return -1;
 }
 else
 {
 return 0;
 }
 }
 #endregion
 public static bool operator <(Kasiyer 
		k1, Kasiyer k2)
 {
 return 
		k1.CompareTo(k2) < 0;
 }
 public static bool operator >(Kasiyer 
		k1, Kasiyer k2)
 {
 return 
		k1.CompareTo(k2) > 0;
 }
 }
 }
 |  
 
  
 Her bir overload edilmiş operatör metotu CIL tarafında özel isimler verilerek adlandırılır.
 
 
 
      En çok kullanılar operatörlerin overload metotlarının CIL deki özel isimleri aşağıdaki tabloda verilmiştir.
        |  | .method  public hidebysig specialname static 
 bool   op_GreaterThan(valuetype OperatörOverloading.Pointy po,
 
 valuetype OperatörOverloading.Pointy  p1) cil managed
 
 
 |  
        | Büyüktur (>) operatöru overload metotunun CIL görünümü. |  
 
 
      Kullanıcı Tanımlı Tip Dönüşümleri(Implicit,Explicit)
        | C# Operatör 
 
 | CIL Karşılığı 
 
 |  
        | –– 
 ++
 
 +
 
 –
 
 *
 
 /
 
 ==
 
 >
 
 <
 
 !=
 
 >=
 
 <=
 
 –=
 
 +=
 
 
 | op_Decrement() 
 op_Increment()
 
 op_Addition()
 
 op_Subtraction()
 
 op_Multiply()
 
 op_Division()
 
 op_Equality()
 
 op_GreaterThan()
 
 op_LessThan()
 
 op_Inequality()
 
 op_GreaterThanOrEqual()
 
 op_LessThanOrEqual()
 
 op_SubtractionAssignment()
 
 op_AdditionAssignment()
 |  
 Aşırı  yükleyebileceğimiz operatörler sadece yukarıda bahsedilen operatörlerden ibaret  değildir.Operatör aşırı yükleyerek Explicit (bilinçli) ve Implicit (bilinçsiz)  tür dönüşümleri de ele alınabilir. Kısaca bilinçli ve bilinçsiz tür  dönüşümlerinin neler olduklarını hatırlayalım. Bilinçli(Explicitly) tür  dönüşümleri küçük bir veri tipinde büyük bir veritipinin değerini saklamak  istediğimizde gerekir. C# tip güvenliğine önem verdiği için böyle bir dönüşüme bilinçsiz(Implicitly)  olarak izin vermeyecektir. Çünkü böyle bir durumda olası bir veri kaybı  yaşanabilir. Bu yüzden bizden ne yaptığımızı bildiğimizi onaylamamızı  isteyecektir. Bu onaylamayı Cast operatörü ile yaparak  derleyiciye “Ben ne yaptığımın farkındayım”  demiş oluyoruz.
 
 
 
      Implicitly  tür dönüşümleri ise küçük tipin büyük tipe atandığı durumlardır. Bu nedenle  daha güvenli dönüşümlerdir ve herhangi bir cast işlemine gerek duymaz.
        | //Explicitly tür dönüşümü ve cast operatörunun  kullanımı long büyükSayi  = 45;
 int sayi = (int) büyükSayi;
 |  
 
 
      Kendi  yazdığımız tiplerimizde bu dönüşümlerin nası uygulandıklarını görmek için iki  adet Minibus(küçük tipi temsil etsin) ve Otobus (büyük tipi temsil etsin)  isimli struct yazalım.
        | //Implicitly tür dönüşümü int sayi2  = 5;
 long büyükSayi  = sayi2;
 |  
 
 
      Şimdide bu yapıları (struct) kullanacak Program.cs dosyamızı  inceleyelim.
        | using System; using System.Collections.Generic;
 using System.Text;
 namespace ImplicitExplicitOpOv
 {
 struct Otobus
 {
 public int koltukSayisi;
 public int ayakta;
 public void YolcuDoldur()
 {
 Console.WriteLine("yolcular otobuse dolduruldu");
 }
 public override string ToString()
 {
 return 
		string.Format("koltuk sayısı {0} ayakta yolcu sayısı {1}", koltukSayisi, 
		ayakta);
 }
 }
 struct Minibus
 {
 public int koltukSayisi;
 public int ayakta;
 public void YolcuDoldur()
 {
 Console.WriteLine("yolcular Minibuse dolduruldu");
 }
 public override string ToString()
 {
 return 
		string.Format("koltuk sayısı {0} ayakta yolcu sayısı {1}", koltukSayisi, 
		ayakta);
 }
 }
 }
 |  
 
 
      Implicitly bir dönüşüm yapmak istediğimizde böyle bir hata alıyoruz. Şimdi de cast işlemi (explicitly tür dönüşümü) yaparak tekrar deneyelim.
        | using System; using System.Collections.Generic;
 using System.Text;
 
 namespace ImplicitExplicitOpOv
 {
 class Program
 {
 static void Main(string[] args)
 {
 //büyük olan 
		tipimizi tanımlayalım ve degerlerini verelim.
 Otobus ikarus 
		= new Otobus();
 ikarus.ayakta 
		= 120;
 ikarus.koltukSayisi = 60;
 //küçük olan 
		tipimizi tanımlayalım ve degerlerini verelim.
 Minibus deutz 
		= new Minibus();
 deutz.ayakta 
		= 15;
 deutz.koltukSayisi=25;
 
 //Error 1 
		Cannot implicitly convert type ’ImplicitExplicitOpOv.Minibus’ to 
		’ImplicitExplicitOpOv.Otobus’ 
		D:\Work\testing\OperatörOverloading\ImplicitExplicitOpOv\Program.cs 19 
		22 ImplicitExplicitOpOv
 
 //küçük tipi 
		büyük tipe atmaya calıstıgımızda yukardaki hatayı alıyoruz...
 ikarus = 
		deutz;
 }
 }
 }
 
 
 |  
 
 
      Explicitly tür dönüşümü yaptığımız taktirdede yukarıda görülen hatayı alırız. O zaman yapmamız gereken yazdığımız bu tiplere tip dönüşümlerini öğretmektir. Yapacağımız işlemler hemen hemen yukarıda yaptığımız Aritmetik ve Mantıksal operatör yüklemelerindekine benzer işlemler olacaktır. Buna göre Otobus ve Minibus yapılarındaki(structs) ilgili güncellemeler aşağıdaki gibidir;
        | // Error    1     Cannot convert type ’ImplicitExplicitOpOv.Minibus’ to ’ImplicitExplicitOpOv.Otobus’ D:\Work\testing\OperatörOverloading\ImplicitExplicitOpOv\Program.cs    26    22      ImplicitExplicitOpOv deutz  =  
		(Minibus)ikarus;
 |  
 
 
      Yukarıdada  görüldüğü gibi, kullanıcı tanımlı tiplere explicitly (cast operatörü ile ) tür  dönüşümünü aritmetik ve mantıksal operatörlerle benzer şekilde öğrettik. Bu  özel metotun erişim belirleyicisi public ve niteleyicisi statik olmak  zorundadır.(Neden public ve static yukarda açıklanmıştır.)
        | struct Minibus {
 public static explicit operator Minibus(Otobus bus)
 {
 //this anahtar sozcugunu static uyelerde kullanamayız!.
 //this.ayakta 
		= bus.ayakta;
 //this.koltukSayisi = bus.koltukSayisi;
 //structlar 
		new anahtar sozcugu ile olusmaya gerek duymazlar.
 Minibus mini;
 mini.ayakta = 
		bus.ayakta;
 mini.koltukSayisi = bus.koltukSayisi;
 return mini;
 }
 }
 |  
 Daha sonra  hangi tür dönüşümünü öğreteceğimizi belirleyen implicit veya explicit anahtar  sözcüklerinden birini seçiyoruz. Operatör anahtar sözcüğünden sonra atama  operatörünün solunda kalacak olan tipi yani dönüştürülecek tipi belirtiyoruz. Bu  tip ayrıca metotun dönüş tipi olarak belirlenip return anahtar sözcüğü ile  döndürmemiz gereken tip haline geliyor.
 
 Metotun  parametre sayısı bir adet olmalıdır. Çünkü dönüşümü yapılacak tür birden fazla  olamaz. Burdanda anlayabileceğimiz gibi, metotun aldığı parametre dönüşmesi  gereken tipi işaret etmektedir.
 
 
  
 Program.cs dosyamıza tekrar bakalım ve değerleri ekrana  yazdıralım;
 
 
 
      
        | class Program {
 static void Main(string[] args)
 {
 Console.WriteLine("******Explicit ve 
		Implicit overloading *******\n");
 //büyük olan tipimizi tanımlayalım ve 
		degerlerini verelim.
 Otobus ikarus = new Otobus();
 ikarus.ayakta = 120;
 ikarus.koltukSayisi = 60+1;
 Console.WriteLine("otobus : 
		{0}",ikarus);
 //küçük olan tipimizi tanımlayalım ve 
		degerlerini verelim.
 Minibus deutz = new Minibus();
 deutz.ayakta = 15;
 deutz.koltukSayisi=25+1;
 Console.WriteLine("minibus : 
		{0}\n",deutz);
 Console.WriteLine("******Explicit 
		atamadan sonra*******\n");
 deutz= (Minibus)ikarus;
 Console.WriteLine("minibus : {0}", 
		deutz);
 }
 }
 |    //Uygulamanın çalıştırıldıktan sonraki  ekran çıktısı.
 
 Kullanıcı  tanımlı iki tip arasındaki bilinçli tür dönüşümlerini gördük. Acaba sistemde  tanımlı tipler ile kullanıcı tanımlı tipler arasındada bu tarz explicit ve  implicit atamalar yapılabilirmi? İsterseniz şimdi de bu soruya cevap  arayalım...
 
 
 
      Bilinçli (explicitly) atama yapılması istenecek  birden fazla farklı tür için aşırı yüklenmiş metotları farklı parametreler alacak şekilde(metot imzası) aşırı yüklüyoruz.
        | public static explicit operator Minibus(int koltukAdet) {
 Minibus mni;
 mni.koltukSayisi = koltukAdet;
 mni.ayakta = 0;
 return mni;
 }
 public static explicit operator int(Minibus mni)
 {
 return mni.koltukSayisi;
 }
 |  
 Program.cs
 
 
 
      
        | Console.WriteLine("***int bir degerin kullanıcı tanımlı tipe explicit  olarak atanması***"); int satinAlinanKoltuk=50;
 Minibus magirus = (Minibus)satinAlinanKoltuk;
 Console.WriteLine("magirus : {0}\n",magirus);
 Console.WriteLine("***kullanıcı tanımlı bir degerin int değere explicit  olarak atanması***");
 
 Minibus schoolBus;
 schoolBus.koltukSayisi = 19+1;
 schoolBus.ayakta = 0;
 int koltuklar = (int)schoolBus;
 Console.WriteLine("koltuk  sayısı : {0}", koltuklar);
 |   
 Uygulamamızın ekran çıktısındanda anlaşılacağı gibi sistemde  tanımlı tipler ve kendi yazdığımız tipler arasında bilinçli tür dönüşümlerini  kendi yazdığımız sınıfta operatör overloading yaparak sağlayabiliyoruz.
 
 Implicitly (bilinçsiz) atamalar küçük bir türün güvenli bir  şekilde büyük türe aktarıldığı atamalardır. Bizde kendi yazdığımız bu iki tip  arasında bilinçiz atamaları gerçekleştirmek için Otobus struct ındaki gerekli  güncellemeleri yapalım.
 
 
 
      Şimdide Program.cs’e dönüp  bilinçiz atama işlemini gerçekleştirmeye çalışalım.
        | struct Otobus {
 public int koltukSayisi;
 public int ayakta;
 public void YolcuDoldur()
 {
 Console.WriteLine("yolcular otobuse 
		dolduruldu");
 }
 public override string ToString()
 {
 return string.Format("koltuk sayısı 
		{0} ayakta yolcu sayısı {1}", koltukSayisi, ayakta);
 }
 public static implicit operator Otobus(Minibus mini)
 {
 Otobus oto; oto;
 oto.koltukSayisi = mini.koltukSayisi;
 oto.ayakta = mini.ayakta;
 return oto;
 }
 }
 |  
 
 
      //program.cs e  eklenecek kod bloğu   
       
       
    Küçük tür  olarak tasarladığımız Minibus nesne örneği bilinçiz bir şekilde daha büyük bir  tür olarak tasarladığımız Otobus nesne örneği üzerine alınıyor. Ekran çıktısına  bakalım ve son durumu öğrenelim.
        | Console.WriteLine("***Implicitly Atamalar***"); Minibus vitobus;
 vitobus.ayakta = 0;
 vitobus.koltukSayisi = 15 + 1;
 Otobus prenses = vitobus;
 Console.WriteLine("otobus  prenses : {0}",prenses);
 |  
 
  
 Minibus yapısından  oluşturduğumuz nesne örneği başarılı bir şekilde otobus nesne örneği üzerine  alınmıştır.
 
 Explicit  atamalarda olduğu gibi imlplicit atamalardada framework’teki tipler ve kendi  yazdığımız tipler arasındada atamalar gerçekleştirebilir.Tek yapmamız gerek  uygun şekillerde operatör overload metotlarının overload metotlarını yazmaktır. Tıpkı diğer operatörde olduğu gibi explicit ve implicit operatörlerde  CIL tarafında özel isimlerle ifade edilirler.
 
 
  
 Operatör aşırı yükleme (overloading) işlemi işleri kolaylaştırmak  için tercih edilir. Eğer yazdığınız sınıflar operatörlerle kullanıldığında  işleri kolaylaştırmıyor aksine anlaşılmaz hale getiriyorsa operatör overload  işlemlerinden kaçınmamız gerekir. Kendi yazdığımız sınıf(class) ve yapı(struct)  larımızda operatör overload işlemlerini akıllıca kullanmalıyız.
 
 Operatör aşırı yükleme konusunu incelemeye çalıştığımız bu makalemizin sonuna gelirken sizlere bir daha ki makalede buluşuncaya dek mutlu günler dilerim.
 
 Umut Özkan
 [email protected]
 
                Makale:Detayları ile Operatörleri Aşırı Yüklemek (Operator Overloading) C#, Visual C# ve .NET Umut Ozkan
 |  
            |  |  
            |  |  
            | 
                    
                        
                            
                        
                            Eklenen Son 10 
                            Bu Konuda Geçmiş 10 
                        
                            Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
                         
                            Son Eklenen 10 Makale Yükleniyor
                         
                            Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
                         |  
            |  |  |