Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

C# 14 ile Extension’lar Baştan Yazıldı: Yeni Syntax Neler Getiriyor?

Merhaba,

C# 14 ile gelen Extension Members özelliği, klasik extension method kavramını ciddi anlamda genişletmekte ve artık sadece metotları değil, property ve field member’larının ve hatta daha organize extension yapılarının yazılabilmesine imkan tanımaktadır. Bu içeriğimizde bu yeniliği baştan sona inceleyecek ve C#’ın yeni gücüne hep birlikte şahit olacağız… Hadi başlayalım…

Extension Members Nedir?

Extension members, C# 3.0’dan beri var olan extension methods yapılanmasının C# 14 ile birlikte çok daha güçlendirilmiş ve genişletilmiş halidir.

Hızlıca extension metotları hatırlamamız gerekirse eğer; elimizdeki herhangi bir türe farklı bir konumdan yeni bir metot/davranış ekleyebilmemizi sağlayan bir teknikti… Misal olarak;

class Person
{
    public string Name { get; set; }
    public string Surname { get; set; }
}

türünü tanımladığımızı varsayalım. Bu türe farklı bir konumdan herhangi bir davranış eklemek istiyorsak burada, aşağıdaki gibi static bir sınıf içerisinde this keyword’ü eşliğinde o türden bir parametreyi alan static özel bir metot tanımlamamız gerekmekteydi;

static class Extension
{
    static public string GetFullName(this Person person)
        => $"{person.Name} {person.Surname}";
}

İşte bu metot, bir extension metottur. this keyword’ü ile belirtilen referansın (Person) instance’ına yeni bir davranış kazandırmaktadır. Böylece, normal şartlarda herhangi bir Person instance’ının member’larına (member access operator ile) eriştiğimiz vakit içinde tanımlanmamış olsa da GetFullName metodunun geldiğini görmekte ve ilgili instance üzerinden erişip, kullanabiliyor olmaktayız.

Tabi, klasik extension metot’larda instance’a sadece metot eklenebilmekteydi; property, field, operator yahut herhangi bir static member vs. eklenememekteydi. Ve hatta aynı türe ait birden fazla extension mantıksal olarak gruplanamamakta, bunlar ayrı ayrı yazılmak mecburiyetindeydi.

İşte C# 14 ile gelen extension members özelliği ile bu kısıtlar ortadan kalmakta ve istenilen türe metotların dışında, property, static member, operator ve (ileride) indexer gibi diğer member’larıda extension olarak ekleyebilme imkanı söz konusu olmaktadır.

Microsoft, C# 14’te gelen bu extension members özelliğine, hedef referansa metotlar dışında diğer member’ları da ekleyebilmemizi sağladığı için bir yandan da Extension Everything adını vermektedir.

Extension Block

C# 14 ile artık bir tipi genişletirken aşağıdaki gibi extension blok tanımlayarak rahatlıkla çalışma sergilenebilmektedir;

static class Extension
{
    extension(Person person)
    {
        public string GetFullNameMethod()
            => $"{person.Name} {person.Surname}";

        public string GetFullNameProperty
            => $"{person.Name} {person.Surname}";
    }

    extension(Person)
    {
        static public string GetTypeNameStaticMethod()
             => nameof(Person);

        static public string GetTypeNameStaticProperty
             => nameof(Person);
    }
}

Klasik extension metotları nasıl ki static class içerisinde tanımlıyorsak extension block’larda aynı şekilde static bir class içerisinde tanımlanmaktadırlar. Dikkat ederseniz hedef referansa özel, birden fazla metot klasik yaklaşımda olduğu gibi ayrı ayrı tanımlanmak yerine bir blok içerisinde kümülatif tanımlanabilmekte ve üstüne birden fazla member ile de ilgili referans extend edilebilmektedir. Ayrıca yukarıdaki örnekte ikinci extension bloğunda olduğu gibi static member’larda sürece dahil edilerek ilgili referans static bellek açısından da extend edilebilmektedir.

Bunların dışında generic type’lar üzerinden de extend işlemi aşağıdaki gibi gerçekleştirilebilmektedir;

static class Extension
{
.
.
.
    extension<T>(IEnumerable<T> source)
    {
        public bool IsEmpty => source.Any();
    }

    extension<T>(IEnumerable<T> source)
    {
        public static IEnumerable<T> EmptyIfNull(IEnumerable<T>? _)
            => _ ?? Enumerable.Empty<T>();
    }
}

Tabi örneklendirme sürecinde normal member’larla static member’lar arasındaki tanım farkını net yansıtabilmek için ayrı extension bloklarda örneklendirmede bulunuyorum. İstendiği taktirde bu member’lar aynı blok içerisinde de tanımlanabilir. Sadece static member’ların static keyword’üyle işaretlenmesi unutulmamalıdır…

Ha static member’ların instance’la işi olmayacağı için extension bloğunun parantezindeki tür genellikle named(isimlendirilmiş) olmayacak şekilde bir tanımda bulunulabilir.

static class Extension
{
.
.
.
    extension<T>(IEnumerable<T>)
    {
        public static IEnumerable<T> EmptyIfNull(IEnumerable<T>? _)
            => _ ?? Enumerable.Empty<T>();
    }
}

Ancak bu kullanım, blokta sadece static üyeler olacaksa geçerlidir. Static ve normal member’ların olduğu durumlarda instance’ı referans edecek olan receiver parametresinin verilmesi mecburiyettendir.

Nihai olarak;
Bu gelişmeyle, extension yapılanmasının olması gereken ideal noktaya vardığını söyleyebiliriz. Klasik yaklaşımı sorarsanız eğer, evet, hala desteklenmektedir. Ancak kısa zamanda esamesi okunmayacak değildir…

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir