C#’da Sihirli Sealed Keyword’ü

Selamlar,

Bu makalede bir çouğumuzun bildiği ama çok da önem vermediği, Sealed keyword’ü hakkında konuşacağız.

Yazdığımız herhangi bir .NET kodu, sonunda makinanın anlayacağı dile dönüşene kadar birden fazla aşamadan geçer. Bu esnada, yazdığımız kod ne kadar net ve belirleyici olursa, derleyici bize o kadar çok yardımcı olabilir ve optimize edilmiş makine kodu oluşturabilir. Bu yazıda, derleyicinin kodumuzu optimize etmesine yardımcı olabileceğimiz yolların bir örneğini tartışacağız. Bu yollardan biri de sealed anahtar kelimesidir.

Sealed keyword’ü, C#’da sınıf tanımında kullanılır. Ve sınıfın, başka hiçbir sınıf tarafından miras alınamayacağını garanti eder.

Bir de, sealed olarak işaretlenen methodlar vardır.

RabbitMQBase: Virtual olarak işaretli bir method, ait olduğu sınıf miras alınınca, aşağıdaki gibi override edilir.

RabbitMQClient: Virtual sealed olarak işaretli bir method, ait olduğu sınıf miras alınsa bile, override edilemez.

SpesificRabbitMQClient (HATALI): Aşağıda görülen kod hata vermektedir. Sealed olarak işaretli ne sınıf ne de method, override edilebilir. RabbitMQClient sınıfından inherit olan SpesificRabbitMQClient sınıfı, “sealed” olarak işarteli “PushPrompt()” methodunu inherit edememektedir.

Gelin, Sealed olarak tanımlanmış sınıfın performansını anlamak için Benchmark testi yazalım.

SealedBenchmarkTest.cs adinda, bir Console Application oluşturalım.

BaseMathClass” adında aşağıdaki gibi Base bir Math sınıfı ve dairenin alanını hesaplayan virtual FindCircileArea() methodu aşağıdaki gibi tanımlanmıştır.

MathClass.cs: Aşağıda görüldüğü gibi, Math sınıfı BaseMath sınıfından türetilip, virtual FindCircileArea() methodu override edilmiştir.

MathSealedClass.cs: Aşağıda görüldüğü gibi, sealed olarak işaretli MathSealed sınıfı, BaseMath sınıfından türetilip, virtual FindCircileArea() methodu gene aynı şekilde override edilmiştir.

Benchmarking.cs:

MathClass ve MathSealedClass sınıflarının FindCircleArea() methodları aşağıdaki gibi çağrılır.

Program.cs: İlgili Benchmark testi aşağıdaki gibi çağrılır.

Benchmark Test Sonucu: Aşağıda görüldüğü gibi Sealed sınıfı üzerinde override edilen Virtual “FindCircileArea()” Method’u, Sealed olmayan sınıfa göre çok daha performanslı çalışmıştır. Peki neden ? Çünkü compiler, bu sınıf nerelerde inherit olmuş diye bir arayış içinde olmamaktadır. Bu da doğrudan virtual methodun çalıştırılma performans’ına yansımaktadır.

Peki Sanal Olmayan Bir Method İle Kıyaslama Yapsa idik Ne Olurdu ?

BaseMathClass: Öncelikle, BaseMathClass’ina aşağıda görüldüğü gibi NonVirtual bir method ekleyelim.

MathClass: Math sınıfının BaseMath sınıfından türemesinden bağımsız olarak, NonVirtual methodu, kendi insiyatifinde tanımlamıştır.

MathSealedClass: Son olarak, MathSealed sınıfında NonVirtual methodu tanımlamıştır.

Benchmarking.cs: Benchmark sınıfı, aşağıdaki gibi değiştirildiğinde Virtual olmayan iki methodun performans testi yapılmış olunur.

Program.cs:İlgili Benchmark testi aşağıdaki gibi çağrılır.

Aşağıda görüldüğü gibi, beklenenin çok dışında bir sonuç ile karşılaşılmaktadır. Nerede ise 2 method, birbirine çok yakın sonuçlar üretmektedir. Yukarıdaki örnek ile karşılaştırıldığında, sealed olarak işaretli bir sınıftaki sanal method ile, normal bir sınıftaki methodda benchmark testine gore 2.93sn – 8.79sn şeklinde büyük bir fark bulunmaktadır.

Buradan çıkarılacak sonuç, kaltım alınılmayacağı garanti bir sınıftaki(sealed) sanal method, derleyici tarafından çok daha performanslı çalıştırılmaktadır.

Son olarak, sınıflarınızı eger baska bir yerde kalıtıma dahil etmeyecekseniz, “Sealed” olarak işaretlemenizi tavsiye ederim. Hatta Microsoft’un başlarda sınıfları default sealed olarak işaretleme planı olduğu ama sonrasında vazgeçildiği söyleniyor.

Geldik bir makalenin daha sonuna yeni bir makalede görüşmek üzere hoşçakalın.

Kaynaklar: https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed

 

Herkes Görsün:

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.