İlkay İlknur

just a developer...

C# 7.0 - Local Functions

Bu makaleye Github üzerinden katkıda bulunabilirsiniz.

Not : Bu makaledeki örnekleri denemek için gereken ortam kurulum bilgisini buradan alabilirsiniz.

C# 7.0 ile beraber gelmesi muhtemel en basit özelliklerden biride local functions özelliği. Hemen örnek yapmadan önce ilk olarak bu özelliğe ne gerek vardı sorusunun cevabını vermeye çalışalım.

Kod yazarken metotların çok fazla uzadığı ve bakımının zorlaştığı senaryolarda metot içerisindeki fonksiyonel bölümleri ayrı bir metot yaparız ve ilgili metot içerisinden de dışarıya aldığımız diğer metodu çağırırız. Bu ufak helper metotlarımız aslında baktığımızda sadece tek bir metot tarafından kullanılırlar ancak tanımlandıkları class'ın bir üyesi olurlar. Dolayısıyla bu helper metotları private olarak tanımlasak bile herhangi bir developer class içerisindeki başka bir metot içerisinden de istemememize rağmen bu metodu çağırabilir.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        //Do something
        HelperMethod();
    }

    private void HelperMethod()
    {

    }
}

Örneğin yukarıdaki kodda HelperMethod isimli metot aynı class içerisindeki başka bir metottan da çağırılabilir.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        //Do something
        HelperMethod();
    }

    private void HelperMethod()
    {

    }

    void Bar2()
    {
        HelperMethod();
    }
}

Bu aslında istenmeyen birşey olsa da bunun önüne geçmek pek mümkün değil. Tek kaçış yolu lambda ifadesi kullanarak Func veya Action tipinde bu helper metotları tanımlamak.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        Action helper = () => { };
        //Do something
        helper();
    }
}

Bu durumda helper kısmı lambda ifadasi ile tanımladığımız için bu lambda ifadesi sadece Bar metodu içerisinden çağırılabilir ve erişilebilir. Böylece aslında en baştan amaçladığımız şeyi gerçekleştirmiş oluruz. Ancak Action ve Func olarak tanımlamanın bazı kısıtlamaları ile performans ve memory bakımından da bazı dezavantajları var.

Sahip oldukları kısıtlamalardan bazıları

  • Lambda ifadeleri generic olarak tanımlanamaz.
  • Lambda ifadeleri içerisinde ref, params ve out olarak parametre tanımlayamayız.
  • Lambda ifadelerini recursive olarak çağırmak için ufak bir trick yapmak gerekiyor. Tanımlama esnasında kendisini çağıramaz.

Tüm bu sıkıntılardan ötürü C# 7.0'da local functions özelliğinin getirilmesi planlanıyor. Şimdi gelelim local functions özelliğinin kullanımına.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        void HelperMethod()
        {

        }

        HelperMethod();
    }
}

Yukarıda da gördüğünüz gibi metot içerisinde yeni bir metot tanımlamaktan başka birşey yapmıyoruz aslında. Dolayısıyla out, ref ve params parametrelerini de kullanabiliyoruz. Ayrıca bu metotların çağırımında da herhangi bir ekstra performans kaybı veya ekstra memory kullanımı da olmuyor. Local functionlar sadece tanımlı bulundukları metot içerisinden erişilebilir durumdalar. Yani başka bir metot içerisinden local function'ın çağırılması gibi bir durum söz konusu da değil. Yukarıdaki kodda da gördüğünüz gibi bir local functionı çağırmadan önce yukarıda o local function'ı tanımlamış olmak gerekiyor. Ayrıca local functionda, içerisinde bulunduğu metot içerisindeki her elemana da ulaşabilirsiniz.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        void HelperMethod()
        {
            foreach (var item in list)
            {

            }
        }

        HelperMethod();
    }
}

C# 6.0 ve C# 7.0 Birarada

Yazıyı sonlandırmadan önce C# 6.0'da gelen expression-bodied function members özelliğini kullanarak local functions tanımlamadan bahsetmek istiyorum. Böylece tek satırlık bir local functionınız olduğunda hızlı bir şekilde bu özelliği kullanarak local functions tanımlayabilirsiniz.

class Foo
{
    void Bar()
    {
        List<int> list = new List<int>();
        void HelperMethod() => Console.WriteLine("Hello");

        HelperMethod();
    }
}

Evet, local functionsla ilgili bu yazıda bahsedeceklerimiz bu kadar. Gördüğünüz gibi ufak ama faydalı bir özellik gibi duruyor. Tabi C# developerların bu özelliği ne kadar benimseyeceklerini de merak etmiyor değilim.

Bir sonraki yazıda görüşmek üzere...



Yorum Gönder


Yorumlar

  • profile

    Oğuz Alp Tan

    • 24
    • 5
    • 2016

    Güzel derleme olmuş yine, selamlar