Caner Tosuner

Leave your code better than you found it

Local Functions C# 7

Local Functions bizlere method scope'ları içerisinde function'lar tanımlamamızı sağlar ve o fonction'ı tıpkı o scope aralığında tanımlanmış bir değişken gibi kullanabiliriz. 

Local Functions C# 7.0 ile gelen oldukça özel tabir edilen feature'lar dan biridir. Local Function tanımladığımız yer bir method, property veya bir constructor olabilir ve IL kodlarına baktığımızda local function'lar compiler tarafından private metotlara dönüştürülürler.

Geliştirme yaparken bir UpdateModel adında bir metodunuzun olduğunu varsayalım ve akış gereği bu metodun içerisinde küçük operasyonel işler yapan kod parçacıkları olduğunu düşünelim. Bu kod parçacıkları sadece o metot tarafından kullanılacağından o metot dışında ayrı bir metot olarak yazma gereği duymayız. Ancak o metoda baktığımızda da belki 200 satırdan fazla koddan oluşmuş ve sürekli kendi içerisinde tekrar eden kodlar içeren bir metot haline gelmiş olabilir. Local function tam da bunun gibi durumlarda karşımıza çıkıyor. O küçük kod parçacıklarını UpdateModel metodu içerisinden ayrı küçük birer metot olarak tanımlayabiliyoruz.

Örnek olarak aşağıdaki gibi küçük bir toplama işlemi yapalım.

public class Program
{
	public static void Main()
	{ 
		int Topla(int x, int y, int z)
        {
           return x + y + z;
		}

		Console.WriteLine(Topla(3, 4, 6));
	}
}

Projeyi çalıştırdığınızda 3,4 ve 6 nın toplamı olan 13 değerini ekranda görüyor olacaksınız.

Local function'lar aynı zamanda tanımlandığı metot içerisindeki değişkenlere de access özelliği taşır. Örnek olarak aşağıdaki gibi bir local function tanımlayabiliriz.

	public static void Main()
	{ 
		int Topla(int x, int y, int z)
        {
           return x + y + z + t;
		}

		int t = 8;
		
		Console.WriteLine(Topla(3, 4, 6));
	}

Local Function'lar kısaca bu şekilde. Küçük bir feature gibi görünse de doğru yerde doğru zamanda oldukça faydalı olacakları kesindir :)

C# 7.0 Yenilikleri

Daha C# 6.0 'ın tüm özelliklerini yeni yeni kavramışken Microsoft C# 7.0 ile gelecek olan özelliklerden bazılarını açıkladı bile. Gelecek olan feature'lara baktığımızda çokta fazla major yenilikler yok gibi ancak yine de kayda değer şeyler var. Gelin bu feauture'ları ufaktan bi inceleyelim

Öncelikle C#7.0 ın özellikleri VS2015'de default olarak yok. Normalde vs2015'de yeni bir proje açtığınızda default C# 6.0 ile gelir. 7.0'ın özelliklerini aktifleştirmek için VS de proje oluştururken ufak bir kaç şey yapmak gerekiyor.

İlk olarak C#da bir tane console proje oluşturalım ve sonrasında solution'da bulunan projeye sağ tıklayıp özellikler diyelim. Açılan ekrandan Build tabına geçelim ve "conditional compilation symbols" textbox'ına __DEMO__ yazalım. Projeyi build ettikten sonra artık C# 7.0 özelliklerini otomatik olarak alacaktır.

 

 

C# 7.0 Features

  • Local functions
  • Binary literals
  • Digit separators
  • Pattern matching
  • Ref returns and locals

 

Local functions

Bir çok yazılım dili fonksiyon içinde fonksiyon yazımına izin verirken C# için bu geçerli değildi. 7.0 ile artık fonksiyon içerisine fonksiyon tanımlıyor olacağız.

public int Method_1(int x,int y)
	{
		int Metho_2(int x)
		{
			return x*x;
		}
	 
		return Metho_2(x)*y;
	}

 

Binary literals and Digit separators

Bu özelliğin aslında 6.0 ile geleceği söyleniyordu ancak galiba yetiştiremediler ki 7.0 ile geliyor. Bu özellikle birlikte artık numeric tanımlamaları binary olarak yazabileceğiz. 

	public void BinaryLiterals()
	{
		var numbers = new[] { 0b0, 0b1, 0b10 };
		foreach (var number in numbers)
		{
		  Console.WriteLine(number);
		}
	}

 

Daha büyük sayıları daha kolay okuyabilmek için ise "_" ayıracını kullanarak digitleri gruplayabiliriz ve bu decimal, hexa veya binary'ler içinde geçerlidir. 

int oneBillion = 1_000_000_000;
int num_1 = 0x7FFF_1234;
int num_2 = 0b1001_0110_1010_0101;

 

Pattern matching

Pattern matching özelliği fonkysionel programlama dillerinde çok yaygın bir özellik ve C# 7.0 da "is" operatörü ile bazı özellikleri bize sunuyor ancak final sürümü ile birlikte daha fazla özellik ekleneceği söyleniyor.

1) Type Pattern

Type pattern reference typle'ların runtime type test işlemi yaparken işimize yarayacak olan bir özellik.

public void Foo(object item)
{
    if (item is string s)
    {
        WriteLine(s.Length);
    }
}

2) Constant Pattern

Constant pattern bir ifadenin runtime değerini test etmek için kullanılır.

public void Foo(object item)
{
    switch (item)
    {
        case 10:
            WriteLine("It's ten");
            break;
        default:
            WriteLine("It's something else");
            break;
    }
}

3) Var Pattern

public void Foo(object item)
 {
     if(item is var x)
     {
         WriteLine(item == x); // prints true
     }
 }

4) Wildcard Pattern

public void Foo(object item)
 {
     if(item is *)
     {
         WriteLine("Hi there"); //will be executed
     }
 }

5) Recursive Pattern

public int Sum(LinkedListNode<int> root)
{
    switch (root)
    {
        case null: return 0;
        case LinkedListNode<int> { Value is var head, Next is var tail }:
            return head + Sum(tail);
        case *: return 0;
    }
}

 

Ref returns and locals

C# ın ilk versiyonundan itibaren "ref" keyword'ünü kullanarak metotlara pass by reference ile parametreler geçebiliyoruz. Bu özellikle birlikte metottan pass by reference ile değer dönmesini sağlıyor.

static void Main()
 {
     var arr = new[] { 1, 2, 3, 4 };

     ref int item = ref Get(arr, 1);

     Console.WriteLine(item); //2

     item = 10;

     Console.WriteLine(arr[1]); //10

     Console.ReadLine();
 }

ref int Get(int[] array, int index)
{
   return ref array[index]; 
}

 

Kısaca C# 7.0 ile gelecek olan feature'lara değindik ancak relase olması için henüz çok erken ve ilerleyen sürümlerde üstte belirttiğimiz özelliklerinin bazıları değişebilir de. 7.0 ile ilgili yeni duyumlar geldikçe de yazmaya devam...