C# 6.0 - Collection Initializers için Add Metodunu Yönlendirmek

Merhaba Arkadaşlar,

Mesleki hayatımın bir döneminde yazılım eğitmeni olarak çalıştım. Ağırlıklı olarak .Net eğitimleri verdim. Tabii o zamanlar .Net nispeten daha kolaydı. Bu kadar fazla dallanan bir Framework değildi ama C# dil özellikleri de acımasızca genişlemiyordu. Aradan geçen onca yıldan sonra çalıştığım turuncu bankanın kendi akademisinden iç eğitim isteği geldi.

Konu C# programlama diliydi. İyi hazırlanmam gerektiği ortadaydı. Kurumsal projelerin standartları gereği en son teknolojiyi kullanamıyor olsak da C# 6.0 dünyasını yakalamıştık. Projelerimizi Visual Studio 2013 ile geliştirmekte ve .Net Framework 4.6.1 sürümünü kullanmaktayız(Şimdilik) Bana sanal bir makine de verdiler ve içerisine gıcır gıcır Visual Studio 2015 koydular(Kurum içinde de Visual Studio 2015 yaygınlaştırılmakta) 

Hal böyle olunca C# 6.0 ile ilgili yenilikleri gözden geçirme fırsatını da yeniden yakalamış oldum. Eğitime hazırlanırken okuduğum özelliklerden birisi de Collection Initializer olarak kullanılabilen Add metodunun istediğimiz bir başka metoda atanabilmesiydi. Bu, özellikle bir koleksiyonu sarmalladığımız IEnumerable türevli tiplerde işe yarayabilecek bir yetenek. Amacımız bir sınıf örneğini oluşturduğumuz yerde içerideki koleksiyona elemanlar atayabilmek. Bunu zaten var olan koleksiyonlar için aşağıdaki gibi yapabiliyoruz.

List<string> colors=new List<string>{
			"red",
			"blue",
			"green"
	   };

Örneğin string tipte elemanlar barındıran colors isimli List<string> nesnesini yukarıdaki kod parçasında olduğu gibi başlatabiliriz. Nesne oluşurken içerisindeki string dizisine ilk elemanlar atanıyor.

Hatta C# 6.0 ile Dictionary<T,K> tipinden koleksiyonları aşağıdaki gibi başlatabiliyoruz da(Kod Visual Studio 2015 de yazılmıştır)

var colors = new Dictionary<int, string>
{
	[100] = "Black",
	[101] = "Green",
	[102] = "Red"
};

Hedefimiz string yerine kendi tipimizi kullanıldığında benzer işlevselliği sunabilmek. Add metodunun olması bunun için yeterli ama bulunduğumuz domain gereği farklı isimli bir metoda atamak isteyebiliriz? İşte soru bu. Konuyu daha iyi anlamak için C# 6.0 öncesinden bir örnekle işe başlayalım. Elimizde aşağıdaki gibi bir sınıf olduğunu düşünelim(Bu örnek Visual Studio 2013 üzerinde geliştirildi)

public class Player
{
	public int PlayerId { get; set; }
	public string Nickname { get; set; }
	public double Level { get; set; }

	public override string ToString()
	{
		return string.Format("{0} {1} {2}", PlayerId, Nickname, Level);
	}
}

Kobay sınıflarımızdan birisi olan Player tipinden generic List<T> koleksiyonu barındıran bir diğer tipimizi de aşağıdaki gibi tasarlayalım.

public class GameSchene
	:IEnumerable<Player>
{
	private List<Player> players = new List<Player>();

	public void Assign(Player player)
	{
		players.Add(player);
	}

	public IEnumerator<Player> GetEnumerator()
	{
		return ((IEnumerable<Player>)players).GetEnumerator();
	}

	IEnumerator IEnumerable.GetEnumerator()
	{
		return ((IEnumerable<Player>)players).GetEnumerator();
	}
}

GameSchene sınıfı IEnumerable<Player> arayüzünü uygulamakta. Buna göre içerideki oyuncu listesi üzerinden for each döngüsü yardımıyla ilerleyebiliriz. Amacımız ise aşağıdaki gibi bir kod parçasını çalıştırabilmek.

class Program
{
	static void Main(string[] args)
	{
		var zone = new GameSchene
		{
			new Player{ PlayerId=102, Nickname="Maykil Cordin", Level=1000},
			new Player{ PlayerId=104, Nickname="a user", Level=800},
			new Player{ PlayerId=89, Nickname="black window", Level=750}
		};

		foreach (var p in zone)
		{
			Console.WriteLine(p.ToString());
		}
	}
}

Aslında string tipinden elemanlar barındıran generic bir kolekisyonu tek ifade içerisinde nasıl başlatabiliyorsak, benzer durumu kendi koleksiyon tipimiz için de yapmak istiyoruz. Ancak kod derlenmeyecek. Nitekim koleksiyon başlatıcısı Add metodunu bekliyor. Örnekte ise Assign metodu var. 

Pek tabii Assign metodunu Add olarak değiştirirsek kod başarılı bir şekilde derlenecek ve çalışacaktır. C# 6.0 tarafında ise Add metodunu extension olarak tanımlayıp istediğimiz başka bir metod ile ilişkilendirme şansına sahibiz. Tek yapmamız gereken aşağıdaki gibi bir genişletme sınıfı yazmak.

public static class GameScheneExtensions
{
	public static void Add(this GameSchene e, Player p) => e.Assign(p);
}

GameSchene tipi için Add isimli bir genişletme metodu söz konusudur. Expression-Bodied Functions özelliği kullanılarak => operatörü sonrası işletilmesi istenen kod tanımlanmıştır. e.Assing(p) ile Add metodunun güncel GameSchene nesne örneğindeki Assing metoduna atanması ve initialization kısmında gelen Player nesne örneğinin parametre olarak atanması sağlanmıştır. Çalışma zamanı çıktısı aşağıdaki gibidir(Örnek Visual Studio 2015 üzerinde yazılmıştır)

Basit ve ince bir özellik bilgimiz olsun mutlaka işimize yarayacaktır. Böylece geldik bir yazımızın daha sonuna. Bir başka yazımızda görüşünceye dek hepinize mutlu günler dilerim.

Yorumlar (5) -

  • Selam.

    Burada neden Assign metoduna ihtiyacımız var? Add metodunu extension metod olarak değil de, GameSchene sınıfının bir metodu olarak yazamaz mıyız?
    • Kendi tipimize { } ile Collection Initializers gibi kullanılma yetisi kazandırıyoruz bu örnekte. Bahsettiğiniz tipte bir extension metod yazdığımızda derleyicinin nasıl davranış göstereceğinden çok emin olamadım Soner Bey.
      • Extension method'a gerek yok. Assign metodunu Add'e çevirin aynı davranışı gösterir.
        • Bu makalede zaten Add method'unu kullanmak zorunda olmadığınızdan bahsedilmiş.
          Böylece method isimlendirirken extension methodları yardımıyla daha fazla özgürlüğe kavuşuyorsunuz.

Yorum ekle

Loading