Yazılım Mimarileri ve Tasarım Desenleri Üzerine

C#’ta Implicit ve Explicit Operatörlerinin Aşırı Yüklenmesi

Merhaba,

C#’ta bilinçli ve bilinçsiz olmak üzere iki tür veri dönüşümü söz konusudur. Bilinçsiz olarak yapılan tür dönüşümü Implicit Conversion şeklinde tarif edilirken, bilinçli dönüşüme ise Explicit Conversion diye nitelendirilmektedir. Hatta biliyorsunuz ki, Implicit Conversion’da herhangi bir operatör yahut ek bir syntax kullanmazken, Explicist Conversion’da “()” – Cast operatörü kullanılmaktadır.

Hatta konuya girişi adım adım yaparak bu iki dönüşümü aşağıda kodsal olarak somutlaştıralım, bir yandan bahsedilenleri hatırlayalım bir yandan da konumuzu ele alalım.

            #region Implicit Conversion
            int x = 135;
            long y = x;
            #endregion
            #region Explicit Conversation
            long x = 1000;
            int y = (int)x;
            #endregion

Hemen hemen her gün yüzlerce kez kulladığınız yapılar… Implicit Conversion ve Explicit Conversation yaklaşımlarını hatırladınız değil mi…

Hatta bu dönüşümleri kalıtım söz konusu olduğu durumlarda kullanmaktayız. Base Class referansına Derived Class nesnesi atarsak eğer Implicit Conversion, Base Class’ları Derived Class’lara Cast edersekte Explicit Conversion kullanmaktayız. Aşağıdaki gibi;

    class Program
    {
        static void Main(string[] args)
        {
            #region Implicit Conversion
            Canli cc = new Insan();
            #endregion
            #region Explicit Conversation
            Canli c = new Insan();
            Insan i = (Insan)c;
            #endregion
        }
    }
    class Canli { }
    class Insan : Canli { }

Şimdi yavaş yavaş asıl konumuza doğru gelelim ve şu soruyu kendimize soralım.

Aralarında kalıtımsal ilişki olmayan sınıflar arasında her iki dönüşümde yaptığımız işlemleri yapmaya çalışırsak ne olur?

Hiç düşündünüz mü?

Biliyorum… Bu soruya hiç düşünmeden hata alırız cevabını verdiğinizi duyuyorum. Hatta aşağıdaki ekran görüntüsü ile sözünüzde ne kadar haklı olduğunuzuda görmenizi istiyorum…

Eğer ki aralarında ilişki olmayan sınıflar arasında Implicit ve Explicit Conversion yapmak istiyorsanız bu sınıfların dönüşüm antlaşmalarını oluşturmanız gerekecektir. Yani demek istediğim custom(özel) conversion tanımlamanız gerekecektir. Yani daha da açıklayıcı konuşmamız gerekirse Implicit ve Explicit operatörlerinin aşırı yüklenmesinden bahsediyorum.

Eğer ki aralarında ilişki olmayan sınıfların Implicit Conversion yapmasını istiyorsak eğer implicit keywordünü(implicit operator), yok eğer Explicit Conversion yapmasını istiyorsakta explicit keywordünü(explicit operator) kullanarak birazdan teknik olarak ele alacağımız şekilde çalışma yapmamız gerekecektir.

Öncelikle, kâh implicit operator kâh explicit operator metodundan hangisi olursa olsun yapısal olarak hangi mantıkta çalıştığını ele alalım.


Şimdi bu konuda aşağıdaki iki sınıfı ele alarak bir kaç örnek gerçekleştirelim.

    class Koordinat
    {
        public int X { get; set; }
        public int Y { get; set; }
    }

    class Lokasyon
    {
        public double X { get; set; }
        public double Y { get; set; }
    }

Bunca yaptığımız örneğin üzerine şunu bilmenizi isterim ki;

Bir sınıf içerisinde aynı işleve sahip hem implicit hem de explicit metot bulunamaz…

Bunun dışında implicit ve explicit metotlar struct yapıları içinde geçerlidir.

    class Program
    {
        static void Main(string[] args)
        {
            MyStruct2 m1 = new MyStruct();
            MyClass m2 = (MyClass)new MyStruct();
            int i = (int)new MyStruct();
            MyStruct m3 = (MyStruct)3;
        }
    }
    struct MyStruct
    {
        public static implicit operator MyStruct2(MyStruct m)
        {
            return new MyStruct();
        }
        public static explicit operator MyClass(MyStruct m)
        {
            return new MyClass();
        }
        public static implicit operator int(MyStruct m)
        {
            return 0;
        }
        public static explicit operator MyStruct(int i)
        {
            return new MyStruct();
        }
    }
    struct MyStruct2 { }
    class MyClass { }

implicit operator ve explicit operator metotlarını her ne kadar kendi oluşturmuş olduğumuz sınıflar arasında kullanabiliyor olsakta; aslında mimarisel olarak gelen ya da dll yahut müdahale edemediğimiz diğer library dosyalarında barındırılan sınıfların kendi yazmış olduğumuz sınıflar ile ilişkisini ve implicit ya da explicit dönüşümlerini ayarlayabilmemizi, bu antlaşmaları sağlayabilmemizi gerçekleştiren metotlardır.

Son olarak bu bahsettiğim konu üzerine Ado.NET’in gözdesi mimariye dahili SqlConnection sınıfı ile yapılan aşağıdaki örneği incelemenizi tavsiye ederim;

    class Baglanti
    {
        public string BaglantiCumlesi { get; set; }
        public static implicit operator SqlConnection(Baglanti b)
        {
            return new SqlConnection(b.BaglantiCumlesi);
        }

        public static explicit operator Baglanti(SqlConnection s)
        {
            return new Baglanti { BaglantiCumlesi = s.ConnectionString };
        }
    }

Kullanımı;

Baglanti baglanti = new Baglanti();
baglanti.BaglantiCumlesi = "Server=...";
SqlConnection con = baglanti;

SqlConnection con2 = new SqlConnection("Server=...");
Baglanti baglanti2 = (Baglanti)con2;

Sabırla okuduğunuz için teşekkür ederim.
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Exit mobile version