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…
C#'ta Implicit ve Explicit Operatörlerinin Aşırı Yüklenmesi

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.
C#'ta Implicit ve Explicit Operatörlerinin Aşırı Yüklenmesi.PNG
C#'ta Implicit ve Explicit Operatörlerinin Aşırı Yüklenmesi.PNG
Ş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; }
    }
  • Koordinat sınıfını Lokasyon’a implicit çevir,
        class Koordinat
        {
            public int X { get; set; }
            public int Y { get; set; }
            public static implicit operator Lokasyon(Koordinat k)
            {
                return new Lokasyon { X = k.X, Y = k.Y };
            }
        }
    

    Kullanımı;

    Lokasyon l = new Koordinat();
    
  • Koordinat sınıfını Lokasyon’a explicit çevir,
        class Koordinat
        {
            public int X { get; set; }
            public int Y { get; set; }
            public static explicit operator Lokasyon(Koordinat k)
            {
                return new Lokasyon { X = k.X, Y = k.Y };
            }
        }
    

    Kullanımı;

    Lokasyon l = (Lokasyon)new Koordinat();
    
  • Lokasyon sınıfını hem Koorinat’a hem de double tipine implicit çevir,
        class Lokasyon
        {
            public double X { get; set; }
            public double Y { get; set; }
            public static implicit operator Koordinat(Lokasyon l)
            {
                return new Koordinat { X = (int)l.X, Y = (int)l.Y };
            }
            public static implicit operator double(Lokasyon l)
            {
                return l.X;
            }
        }
    

    Kullanımı;

    Koordinat k = new Lokasyon();
    double i = new Lokasyon();
    
  • Lokasyon sınıfını hem Koorinat’a hem de double tipine explicit çevir,
        class Lokasyon
        {
            public double X { get; set; }
            public double Y { get; set; }
            public static explicit operator Koordinat(Lokasyon l)
            {
                return new Koordinat { X = (int)l.X, Y = (int)l.Y };
            }
            public static explicit operator double(Lokasyon l)
            {
                return l.X;
            }
        }
    

    Kullanımı;

    Koordinat k = (Koordinat)new Lokasyon();
    double i = (double)new Lokasyon();
    
  • Koordinat ve Lokasyon sınıflarını sırasıyla double ve bool türlerine implicit çevir.
        class Koordinat
        {
            public int X { get; set; }
            public int Y { get; set; }
            public static implicit operator double(Koordinat k)
            {
                return k.X * k.Y;
            }
        }
    
        class Lokasyon
        {
            public double X { get; set; }
            public double Y { get; set; }
            public static implicit operator bool(Lokasyon l)
            {
                return true;
            }
        }
    

    Kullanımı;

    double d = new Koordinat();
    bool b = new Lokasyon();
    
  • Koordinat ve Lokasyon sınıflarını sırasıyla double ve bool türlerine explicit çevir.
        class Koordinat
        {
            public int X { get; set; }
            public int Y { get; set; }
            public static explicit operator double(Koordinat k)
            {
                return k.X * k.Y;
            }
        }
    
        class Lokasyon
        {
            public double X { get; set; }
            public double Y { get; set; }
            public static explicit operator bool(Lokasyon l)
            {
                return true;
            }
        }
    

    Kullanımı;

    double d = (double)new Koordinat();
    bool b = (bool)new Lokasyon();
    

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…

Bunlar da hoşunuza gidebilir...

4 Cevaplar

  1. Atılgan dedi ki:

    Faydali bir yazi tesekkurler.

  2. Mustafa dedi ki:

    Gayet açıklayıcı teşekkürler

  3. UMUT dedi ki:

    Gerçekten çok başarılı bir anlatım ve çalışma olmuş ayriyetten anlatım ve örnekler ve anlatım oldukça açıklayıcı elinize ve emeğinize SAĞLIK..
    TEŞEKKÜRLER…

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*