C# Operator Overloading (Operatör Aşırı Yükleme)

Merhaba arkadaşlar,

Bu yazımda Sınıfları daha etkili kullanmak ve sınıflara yeni anlamlar yüklemek için C#’ta Operatör Aşırı Yükleme (Operator Overloading) konusunu ele alacağız. İçeriğe başlamadan önce eğer Sınıflar ile ilgili eksikleriniz varsa C# Classes (Sınıflar) yazıma bakmanızı tavsiye ediyorum. Yazıya buradan ulaşabilirsiniz.

Bu yazıda bahsedilecek konular

  • Operatörlere Aşırı Yükleme (Operator Overloading)
  • Aritmetik Operatörlerin Aşırı Yüklenmesi
  • İlişkisel Operatörlerin Aşırı Yüklenmesi
  • treu false Operatörlerin Aşırı Yüklenmesi
  • Mantıksal Operatörlerin Aşırı Yüklenmesi
  • Dönüşüm Operatörlerin Aşırı Yüklenmesi

Giriş

Sınıflarımız için tasarlayacağımız en etkili elemanlar operatör metotlarıdır. Operatör metotlar bir nesnenin ifadeler içinde operatörlerle kullanıldığı zaman davranışlarını belirler. Örneğin int türünden nesneler için + operatörü iki sayının toplamını ifade eder. Aynı şekilde * operatörü iki sayının çarpımını ifade eder. Temel veri türleri için operatörler zaten belirlenmiştir. O yüzden temel veri türlerine müdahale edemeyiz. Ancak kendi geliştireceğimiz sınıflar için ihtiyacımıza göre operatörlere yeni anlamlar yükleyebiliriz.

Yukarıdaki örneğe baktığımızda + operatörü kullandığımızda sınıfımız + operatörü ile ne yapacağını anlamaz çünkü + metot operatörünü tanımlamadık. İşte bu tür kullanımlardan kaçmak için operatör metotları tanımlarız.

Yukarıdaki örneği iki sayının toplamı gibi yapmaya çalışırsak + operatörü ile bunu gerçekleştirebiliriz.

operator+ metodu ile kendi sınıfımıza bu operatörü gördüğünde nasıl davranması gerektiğini bildirdik. Bu sayede sınıfımızı aritmetik işlemler için kullanabiliyoruz.

Aslında operatör metotlarının sonuçlarını daha önce gördük ama fark edemedik. String türünde iki farklı nesneyi topladığımızda iki yazıyı arka arkaya eklediğini hatırlarsınız. İşte tam bu noktada String türü için +operatörü devreye giriyor ve gizlice aşağıdaki metot çağrımı yapılır;

Operatör metotları ile ilgili bilinmesi gerekenler;

  • operatör metotlar statik olarak tanımlanmalıdır.
  • Operatör metot tanımlamaları için operatör anahtarı kullanılır. Ör -> operatör+, operatör* gibi
  • Bütün operatör metotların mutlaka bir parametresi olmalıdır.
  • Operatör metotlarda klasik metotlar gibi aşırı yüklenebilir.
  • Tekil (unary) operatör metotlarında parametre mutlaka ilgili sınıfın türünden olmalıdır. Binary (iki operand alan) operatör metotlarında ise en az bir parametre ilgili sınıfın türünden olmalıdır.
  • Operatör metotlar ref ve out anahtar kelime ile kullanılmamalıdır.

Aritmetik Operatörlerin Aşırı Yüklenmesi

Aritmetik operatörler sınıflar gibi aşırı yüklenebilir demiştik. Bu bilgiye istinaden operatör metodumuzu bir tam sayı ile toplamak istersek;

Şimdi ise diğer aritmetik işlemleri sırasıyla operatör metotlarını bildirmeye başlayalım.

İlişkisel Operatörlerin Aşırı Yüklenmesi

İlişkisel operatörler true ya da false değeri ile geri dönmelidirler. Bu yüzden bu tür operatörlerin metotlarını yazarken buna özen göstermeliyiz. İlişkisel operatörler 6 tanedir. Bunlar: !=, ==, <, >, <=, >=. Bu operatörlerin aşırı yüklenmesi ile ilgili tek kural zıt anlamlı operatörlerin her ikisininde bildirilmesi gerekli.

true ve false Operatörlerinin aşırı yüklenmesi

true ve false operatörlerinde aynı anda olmak şartıyla aşırı yüklenebilir. Bu tür operatörlerin metotları genellikle ilişkisel operatörlerin ve mantıksal operatörlerin ifadelerde sıkılıkla kullanılmasının mantıklı olduğu durumlarda yüklenir.

Mantıksal Operatörlerin Aşırı Yüklenmesi

Mantıksal operatörleri yükleme konusunda iki kısımda incelemeliyiz. ( &, |, !, && ve ||) operatörleri C#’ta mantıksal operatörlerdir. Bu operatörlerin yüklenebilmesi içim bir takım ön şartlar var. Bu operatörlere kısa devre operatörleri de hatırlayalım!

Şimdi sınıfımız için (&, ! ve |) operatörlerini tanımlayalım

Şimdi ise kısa devre operatörlerini tanımlayalım. (&& ve ||) operatörlerinin aşırı yüklenebilmesi için bir takım şartların yerine getirilmesi gerekiyor. Bu şartlar;

  • & ve | operatörleri aşırı yüklenmiş olur
  • true ve false operatörleri aşırı yüklenmiş olur
  • operator & ve operator| metotlarının parametreleri ilgili sınıfın türünden olmalı.
  • operator& ve operator | metotlarının geri dönüş değeri ilgili sınıfın türünden olmalıdır.

O halde elimizde var olan bir takım şartları yerine getirmeye başlayalım. true ve false operatörlerini zaten daha önce tanımladık. operator& ve operator| metotlarını yeninden düzenleyelim.

Dönüşüm Operatörlerinin Aşırı Yüklenmesi

Tasarladğımı sınıfların temel veri türleri ile ya da tanımladığımız diğer sınıflar ile uyumlu çalışabilmesi için tür dönüştürme işlemleri ile aşırı yüklenebilir.

Normal şartlarda yukarıdaki dönüşüm derleyici tarafından derlenemez. Çünkü OperationManager türünden bir nesne int değerine atanmaya çalışıyor ve derleyici bunu nasıl çözümleyeceğini bilemez. Hatırlarsanız yukarıdaki kullanım bilinçsiz (implicit) dönüşümüdür. Bunun tam tersi yani bilinçli (explicit) dönüşümler içinde aynı şeyleri söylemek mümkün.

İşte bu tür dönüşümleri yapabilmek için tür dönüştürme operatör metotları bildirilir.

Yukarıda verdiğimiz implicit örneğin geçerli olabilmesi için dönüşüm operatörünü kullanalım. Buna göre aşağıdaki ifade int türüne dönüşümde geçerli olur.

Yukarıda verdiğimiz explicit örneğin geçerli olabilmesi için dönüşüm operatörünü kullanalım. Buna göre aşağıdaki ifade int türüne dönüşümde geçerli olur.

Dönüşüm operatörleri ile ilgili bilmemiz gereken önemli bir kısıtlama vardır. Yukarıdaki iki metot bir sınıf içinde aynı anda tanımlayamayız. Yani geri dönüş türü ve parametresi aynı olan iki metot bildiremeyiz. Ancak implicit operatör metotları bildirildiğinde explicit tür dönüşümleri de yapılabilir. Ancak explicit operatör metotlarda bu geçerli değil.

Diğer bir önemli nokta ise tür dönüştürme operatörleri ile bilinçli (explicit) yapılan dönüşümlerinde herhangi bir veri türüne dönüşüm yapabilmemizdir. Buna göre aşağıdaki bilinçli tür dönüşümü geçerli olacaktır.

Unutma: Burada hatırlanmalıdır ki int türü byte türüne dönüştürüldüğü zaman veri kaybı olma ihtimali vardır. Eğer öyle bir ihtimal var ise explicit operator tanımlamasını kullanmalıyız.

Şimdi bu yaptığımız işlemlerin tersini yapalım. Yani OperatorManager nesnesine başka türden bir nesneyi atamaya çalışalım. O zaman aşağıdaki durum geçerli olur.

C#’ta birçok operatörün nasıl aşırı yüklendiğini inceledik. Operatörleri yüklerken operatör öncelik sırasını değiştiremeyeceğimiz gibi temel veri türleri için operatörleri yeninden yükleyemeyiz!

Bu yazımda C# Operator Overloading (Operatör Aşırı Yükleme) hakkında edindiğim bilgileri paylaşmaya çalıştım. Umarım faydalı olmuştur.

Bir sonraki yazımda görüşmek üzere 🙂

Kaynaklar:

Her Yönüyle C# 7.0, Sefer Algan, Pusula Yayincilik

https://docs.microsoft.com/tr-tr/dotnet/api/system.io?view=netframework-4.8

Leave a Comment