“Implicit” ve “Explicit” kelimeleri, C# ile geliştirme yapan herkesin zaman zaman oldukça kullandığı kavramlar. Tipler arası çevrimler için tercih ettiğimiz iki farklı yöntem aslında…”Implicit Conversion” ve “Explicit Conversion”. Hatırlamak adına aşağıdaki kod örneği yeterli olacaktır sanırım. Syntax olarak aralarındaki fark, Explicist Conversion’da “(type)” şeklinde cast operatörünün olması.
Implicit Conversion
int number = 3; double doubleNumber = number;
Explicit Conversion
double average = 4; int avg = (int)average;
Oldukça basit ve tanıdık, değil mi… Bu noktadan itibaren bu cast işlemlerini, operatör overloading’e benzer bir şekilde nasıl kendi objelerimiz için yapabiliriz bundan bahsetmeye çalışacağım. Açıkçası çok tercih edildiğini düşünmüyorum, ama yeri geldiğinde bir kaç problemi çözmede yardımcı olabilir.
Geliştirilmesine müdahale edemediğimiz ve artık geliştirilmeyen kütüphaneler ile geliştirilmiş legacy sistemlere müdahale etmemiz gerektiğini düşünelim. Her yazılımcının rüyası…Daha doğrusu kabusu. Neyse…Bu kütüphanelerdeki tipleri, kendi geliştirdiğimiz yeni tiplere çevirmemiz gerektiğinde, çeşitli Helper sınıfları ve metodları ile “conversion” işlemlerini yapabiliriz. Buna ek olarak, conversion(cast) operatörünü kullanarak da basitçe yapabiliriz.
Aşağıdaki gibi bir birinden bağımsız iki tane sınıfımız olsun. Burada bağımsız derken Dolar sınıfı, XYZ assembly’sinde, TL sınıfı da ABC assembly’sinde olsun…Ve TL sınıfı bizim geliştirdiğimiz yeni bir sınıf olsun. Yani biraz daha kontrolü bizde. Bu şekilde bir senaryo ile çözüm sağladığı nokta daha iyi anlaşılabilir diye düşünüyorum.
public class Dolar { public double Value { get; set; } public string Sign { get; private set; } public Dolar(double v=0) { Sign = "$"; Value = v; } } public class TL : Currency { public double Price { get; set; } public string Sign { get { return "₺"; } } } public abstract class Currency { }
Dolar sınıfından yarattığımız bir nesneyi, TL sınıfından bir nesneye çevirmek istediğimizde aşağıdaki gibi bir cast işlemi ile yapabiliriz. Ama tabi ki Dolar sınıfı, TL sınıfından türemediği için hata alırız.
class Program { static void Main(string[] args) { Dolar dolar = new Dolar(250); TL test = (TL)dolar; } }
Burada yapmaya çalıştığımız aslında “Explicit Conversion”. Ama cast operatörü diyebileceğim “(type)” operatörü bu tipler için geçerli olmadığından, “Cannot convert type” hatasını alıyoruz.
explicit anahtar kelimesini kullanarak ve operator overloading yaklaşımı ile yapmaya çalıştığımız “Explicit Conversion” işlemini hata almadan, sorunsuz bir şekilde gerçekleştirebiliriz. Bunun için aşağıdaki static metodu TL sınıfına eklememiz yeterli olacaktır.
public class TL : Currency { public double Price { get; set; } public string Sign { get { return "₺"; } } public static explicit operator TL(Dolar dolar) { return new TL { Price = dolar.Value * 2.48 }; } }
Bu metodun içerisinde “conversion” işlemi için yapılacak, ekstra şeyleri ihtiyaç doğrultusunda yapmak oldukça kolay artık.
Eğer “Implicit Conversion” yapmak istiyorsak da “explicit” anahtar kelimesini, “implicit” ile değiştirmek yeterli olacaktır.
public class TL : Currency { public double Price { get; set; } public string Sign { get { return "₺"; } } public static implicit operator TL(Dolar dolar) { return new TL { Price = dolar.Value * 2.48 }; } }
Bu sayede artık cast işlemi yapmadan da, sınıflarımızı bir birine çevirebiliriz.
class Program { static void Main(string[] args) { Dolar dolar = new Dolar(250); TL test = dolar; } }
Küçük ama önemli bir hatırlatma; implicit ve explicit operator’leri aynı anda sınıf içerisinde tanımlanamaz.
C#’ın bilinen ama farkında olunmayan bu özelliği umarım bir yerde faydalı olur size de… Şimdilik bu kadar…