27 Temmuz 2010 Salı

Lambda Operatoru

C# 3.0 yeniliklerinden biri de lambda operatorudur. Lambda operatorunun aslinda spesifik bir gorevi yoktur. Sadece anonim metot yazarken kullandigimiz komutlarin bazilarini bize kullandirmadan daha basit ve islevsel bir kodlama imkani sunar. Anonim metotlari, biz LINQ'da kullanacagimizdan bazen gercekten cok uzun kodlamalarla karsi karsiya kalabiliriz. Bu durum kodun okunulurlugunu ve ileride yapilacak olan bir degisiklikte kodlamanin bozulmadan degisiklik yapilmasini zorlastiracagindan lambda operatoru sayesinde bu dert ortadan kalkmis olacak. Simdi kisaca nasil kullanildigini ve eski uzun kodlamalari nasil kisalttigini kisaca ornek uzerinden anlamaya calisalim.

delegate void Temsilci(int a);
delegate int IslemHandler(int a,int b);

Temsilci t = delegate(int a)
{
Console.WriteLine(a * a);
};

Bunu lambda operatoru ile yazarsak;

Temsilci t2 = (int a) =>
{
Console.WriteLine(a*a);
};
Lambda kolayliklarindan faydalanmadik henuz.
Lambda ile kisaca yazmak istersek;

Temsilci t3 = a =>
Console.WriteLine(a * a);

Lambda operatoru ile yapilan kisaltmalarda su maddeler dikkate alinir:
  • Parametrelerin tiplerini soylememize gerek yok delegeden biliyo imzasini.
  • Tek parametre varsa parantezlere gerek yok.
  • Metodun icinde tek satir kod varsa suslu parantezlere de gerek yok.
Lambda operatorunu geri deger donen anonim metotlarda da kullanabiliriz;

IslemHandler islem = (int a, int b) =>
{
return a + b;
};
veya daha kisa yazarsak

IslemHandler islem2 = (a, b) => a + b;

delege baglama olayi da su sekilde gerceklesiyor.

islem2 += (a, b) => a * b;

26 Temmuz 2010 Pazartesi

C# 3.0 Yenilikleri - II

1-Object Initializer:
Nesne orneklemesi yapilirken, eger kullanilan class'in constructori asiri yuklenmisse, bizden asiri yuklenen parametrelerin girisi zorlandirilir ide tarafindan. Yani ornegin Urun classimizin constructori su sekilde ise,

public Urun(int id,string ad,double fiyat)

ise biz bu sinifin orneklenmesini yaparken;

Urun urn=new Urun(1,Monitor,100);

yapmamiz gerekecekti. Bu basit bir ornekti. Diyelim ki projemiz daha uzun ve komplike fieldlara sahip olsun, o zaman surekli constructorlari overload mi edecektik. Onlarca constructor mi yazmamiz gerekecekti. Cevap ne yazikki evet. Iste C# 3.0 yeniligi ile birlikte artik bu cevap hayir olacak :) Hemen ornekte gosterelim;

Urun u = new Urun() { Id = 1, Ad = "Monitor", Fiyat = 200 };

Bizim arka planda ayrica 3 parametreli constructor yazmamiza gerek kalmayacak boylece. Ne kadar guzel bir ozellik degil mi?

Not: Bu ozellik bize ctor'u kullanma demek olmuyor. Ctor'larin isimize gercekten buyuk olcude yarayan cok onemli gorevleri vardir, bu gorevlerden yararlanmak istedigimiz zaman kullanabiliriz. Peki nedir bu gorevler;
a)Kullaniciyi deger girmeye zorlamak
b)Nesne orneklenirken bir takim kodlari calistirabilmek.
2-Extension Methods: Extension metod bir nesne uzerinde is yapan static bir metodu, sanki o nesnenin nonstatic bir metoduymus gibi cagirma imkani saglar.

public static void BenHerYerdeCikarim(this object obj)
{
//toString() gibi tum object nesnelerde gorulebilecek.
}
public static void Test(this IComparable obj)
{ }

* this anahtar sozcugu sayesinde o tipe ait nesnelerin bir uyesi gibi artik intellisensede bize gorunecektir. Yani biz object a; veya IComparable a; diye tanimlama yaptiktan sonra a. dersek intellisensde BenHerYerdeCikarim veya Test metotlarini gormus olacagiz. BenHerYerdeCikarim metodu object siniflara eklendiginden ToStrign() metodu gibi tum nesnelerde cikabilecek.

Butun bu uyeler (object,IComparable ... vs.) turetmeye uygun class olduklarindan biz bunlari turetip, bu classlara kendi metotlarimiz ekleyebiliyorduk. Peki bizim classimiz kalitim dusmani olan sealed olsaydi. Hemen en basit ornegi

Public sealed class String;

Stringleri kalitamadigimizdan o sinifa metot da ekleyemiyoruz. Peki bu durumda ne yapacagiz. C# 2.0 ile gelen bir ozelligi kullanip, classlara da static anahtar sozcugunu ekleyerek artik istedigimiz islemi yapmis olacagiz.

public static string RemoveNonNumeric(this string str) //this ile o sinifin uyeyisinin ozelligiymis gibi yenilik getirdik.sonuc. diyince cikiyo artik...
{
string res = string.Empty;
foreach (char c in str)
{
if (char.IsNumber(c))
{
res += c;
}
}
return res;
}



3-Collection Initializer: Kullanisli bir C# 3.0 yeniligi daha. Anlatmaya pek gerek kalmayacak, ornegini gosterdigim zaman anlasilacaktir.

List sayilar = new List() { 5, 10 };
ile simdi yazacagim kod arasinda hic bir fark yoktur.

sayilar.Add(5);
sayilar.Add(10);

25 Temmuz 2010 Pazar

C# 3.0 Yenilikleri - I

1-Auto Implemented Property: C# 3.0 yeniliklerinden biridir. Kendilerinin gorevi kisaca sudur ki, eger bir sinif icerisine private bir field yazilip, get ve setlerinde herhangi bir islem yapilmiyorsa, kisaca bizim prop yazip iki kere taba bastigimiz zamanki olusan yapi yazilabilir.

public int Id { get; set; }
public string Ad { get; set; }
public double Fiyat { get; set; }

2-Implicitly Typed Local Variables: Ileriki konularda cok sık kullanacagiz aslinda bu ozelligi. Kisaca ornek uzerinden aciklarsak;

int a=5;
var a=5;

arasinda hic bir fark yoktur. Ide'miz kendisi 5'in int oldugunu anlayip otomatik olarak var a'yi int ozelligine sokuyor.
Kendileri object bir tip olup, mscorlib.dll'i icinde yer alir. Birkac ufak dipnotlar;

1-var e;
var f=null; //bunlar hatali kullanimlardir.
2-Sadece Lokal degiskenlerde kullanilabilirler.
3-Linq'da ve yine c# 3.0 ile gelen anonim tiplerde kullanilirlar.

*** Var, bir tip degildir. Sadece, sag taraftan atanan uyenin tipini anlayip, kendini o tipe donusturen bir "keyword"dur.

3-Anonim Tipler:
Tasarim yapilmis siniflarin nesnelerini olusturmamizi saglayan bir C# 3.0 yeniligidir. Var anahtar sozcugu, arka tarafta olusan sinifin adini temsil etmektedir. Cunku o sinifin adini kod icinde ele alamiyoruz.!

var v=new { Marka = "Renault", Model = "Megane", Hiz = 200 };
Console.WriteLine(v.ToString());//ToString() metodu override ediliyor aslinda.


Anonim Tipler, LINQ sorgulari icinde kullanilir.Bunun idsindaki sinfilari yine bu sekilde yazmaya devam edecegiz.
4-Implicitly Type Arrays: C# 3.0 yeniliklerinden biri de implicitly type arraylerdir. Gelis amaci tamamiyle Anonim tiplerin dizilerini yapmaktir. Kullanimi oldukca basittir, asagidaki ornek yeterince aciklayici olacaktir.

var elemanlar = new[]
{
new{ X=1,Y=2},
new{ X=1,Y=2},
new{ X=1,Y=2}
};

22 Temmuz 2010 Perşembe

C#'da Event Kavrami

Delegelerde de anlattigimiz gibi eventler C# icerisinde buyuk bir oneme sahiptir. Yaptigimiz tum isler aslinda arka planda eventlerin tetiklenmesi sonucu yapilmasi istenilen gorevlerin yapilmasi sonucunda ortaya cikar. Visual Studio sagolsun cogu eventi kendi hazir veriyor, bize sadece yapilmasi istenen goreve gore kod yazmak dusuyor. Simdi biz de kendi eventimizi kendimiz yaratarak bu islemlerin arka planda nasil gerceklestigini inceleyelim.
Senaryomuz basitce soyle olsun. Degiskenleri hic uzatmadan basit bir ornek uzerinden gidiyorum. Stok takip programimiz olsun. Degisken olarak sadece int stok olsun ve stok sayimizi 5er 5er azaltalim. Stok sayisi 10un altina dustugu andan itibaren bize stok azaliyor uyarisini versin. Amacimiz bu. Normalde nasil bir yaklasim uygulanir, if bloklarini yazarsiniz 10dan kucukse sunu yaptir, degilse sunlari yaptir vs. Event tabanli programlamayi kullanarak yapinca daha profesyonel bir yapi olusturmus olacagiz. Aslinda Event'lerin gucunu kavramak icin basit bir ornek bu, daha komplike bir sorunla karsilastigimizda eventlerin gercek gucunu goruruz ama simdilik biz hem hatirlatma maksatli, hem de bilmeyenler icin ogrenme maksatli ufak bir program yazalim.



namespace Event_App_
{
    class Program
    {
        static void Main(string[] args)
        {
            Urun urn = new Urun(50);
            urn.KatDegisti += new Temsilci(urn_KatDegisti);
            for (int i = 0; i < 10; i++)
            {
                urn.StokDurumu();
            }
        }
        static void urn_KatDegisti()
        {
            Console.WriteLine("Stok bitmek uzere...");
        }
    }
    delegate void Temsilci();
    class Urun
    {
        private int stok; 
        public event Temsilci KatDegisti; 
        public int Stok
        {
            get { return stok; }
            set
            {
                stok = value;
                if (value <= 10 && KatDegisti != null)
                    KatDegisti.Invoke();
            }
        }
        public Urun(int stok)
        {
            Stok = stok;
        }
        public void StokDurumu()
        {
            Stok -= 5;
            Console.WriteLine(Stok);
        } 
    }
}

20 Temmuz 2010 Salı

C#'da Delegeler(Delegates)

Method'larimiz calisma aninda RAM'de yer tutarlar, dolayisiyla bir metodun RAM'deki baslangic adresi soz konusudur. Delegeler kisaca, metotlarin bu baslangic adreslerini tutabilen nesnelerdir. Peki biz nerelerde kullanacagiz bunlari. Madde madde siralama yapmadan once kisaca aklima gelen ilk ornegi vereyim. Bir stok takip programiniz var ve stok miktariniz 50nin altina dusunce uyari vermesini istiyorsunuz. Ya da baska gorevler de verdirebilirsiniz. Iste burada delegeleri rahatlikla kullanabiliriz. Yani o metodun calismasi icin(gorev verdigimiz) tetiklenecek bir olay gerekiyor. Iste bunu delegeler yardimiyla yapiyoruz. Aslinda burada farkinda olmadan delegelerin event programlamada kullanildigini belirttik.
Delegelerin Framework icinde yogun kullanildigi yerler;
1-Event tabanli programlama
2-Asenkron programlama
3-LINQ

Simdi kisaca delegelerin nasil tanimlandigini ve baglama islemlerinin nasil yapildigini inceleyelim.
delegate int Temsilci(int a);

Ustteki delege bize, int parametresi alip geriye int donduren bir metodun adresini tutacagini soyler.
Not: Yazdigimiz metodun private ... vs. olmasi onemli degil. Hangi tur erisim belirleyicisine sahip olursa olsun delegelerin tanimlanma bicimi bu sekilde olacak.

Temsilci t = new Temsilci(KareAl);
t += KupAl;
ConsoleWriteLine(t.invoke(5)); // a=5 icin delegelerin cagrilmasi.

Metotlarimiz ise su sekilde;

static int KareAl(int a)
{
return a * a;
}
static int KupAl(int a)
{
return a * a * a;
}

Yukaridaki sonuca gore ciktimiz 25 ve 125 olacaktir. Bir sonraki makalemizde, event tabanli programlamayi anlattigimizda daha da anlasilir olacaktir bu yazdiklarimiz.