İlk olarak 2005 yılındaki PDC (Professional Developer Conference) ile duyurulmuştur. Yenilikler içerisinde ilk göze çarpan özellik veri türü tanımlama işlemlerinin yapılmasına gerek kalmamasıdır. İlk atanan değerin türü veri türü olarak oluşturulmakta, bunun haricinde Lambda ifadeleri ve LINQ en önemli yeniliklerdir.
Tür belirtilmeden türetilen değişkenler C# 3.0 ile gelen ve en sık kullanılan özelliklerden birisidir. Yeni bir değişken tanımlarken daha önce olduğu gibi değişkenlerin türlerini belirtmek yerine var anahtar sözcüğü kullanılarak türünü vermeden değişken tanımlama imkanına sahip olunmaktadır. Değişkenlerin türlerinin belirlenmesi derleme zamanında belirlendiğinden herhangi bir performans kaybına da neden olmamaktadır. Bu özellik kullanılırken unutulmaması gereken nokta yaratılan değişkenin o anda atama işlemine tabi tutulmasıdır yoksa bu değişken tanımı geçersiz sayılmaktadır.
var ogrenciAdi = "TestOgrenci";
var numarasi = 60519;
Console.WriteLine(ogrenciAdi.GetType());
Console.WriteLine(numarasi.GetType());
Console.WriteLine(ogrenciAdi + "öğrencinin numarası: " + numarasi);
Bu özellik kullanılırken dikkat edilmesi gereken bir diğer nokta ilk tanımlama yapılırken atanan değer daha sonra başka bir atama ile değiştirilmek istendiği takdirde yeni değerinde önceki değer ile aynı olması gerekmektedir.
Değişkenlerde olduğu gibi veri türleri oluştururken de var anahtar sözcüğü kullanılabilir.
Yapıcılandırıcıların aşırı yüklenmesi Nesnelerin oluşturulması sırasında o sınıfa ait yapıcı yordam kullanılmaktadır. Farklı sayıda veya türde parametre kullanmak için yapıcılara aşırı yükleme yapmak mümkündür. C# 3.0 ile bu biraz daha geliştirilerek nesneye ait özellikler tek bir yapıcı üzerinde tanımlanarak kullanılabilmektedir. Bu sayede girilecek parametrelerin sayısına göre farklı yapıcı yordamlar oluşturulmamış olacaktır.
public class iletisimBilgi
{
public int telefon;
public string adres;
}
public class ogrenci
{
public int ID;
public string isim;
public iletisimBilgi iletisim;
}
var ogrenci1 = new ogrenci { ID = 34567 };
var ogrenci2 = new ogrenci { isim = "TestOgrenci", ID = 34578 };
Parçalı Metotlar (Partial Methods)
Parçalı sınıflardaki yapıya benzer şekilde C# 3.0 ile birlikte metotları da partial (parçalı) tanımlamak mümkün olmaktadır. Böylece yazılım geliştiricinin kodunun herhangi bir yerinde tanımlamış olduğu bir metodun işlevlerini tanımlaması için o koda bağımlı kalması gerekmez.
Metodun tanımlanması ve kullanılması farklı alanlarda yapılabilir hale gelmektedir. Parçalı metotların tanımlanması sırasında partial sözcüğü kullanılmalıdır ve her zaman void dönmek zorundadır. Parçalı metotlar tanımlandıklarında private olarak oluşturulurlar. Parçalı metotlar için delegate (temsilci) oluşturulamaz.
Genişletme Metodları (Extension Methods) Genişletme metotları C# 3.0 ile birlikte gelen yeni yapılar ve önceki versiyonlarda yer alan metotların kullanımının devamının sağlanması için kullanılmaya gerek duyulmuştur. Genişletme metotları ile sahip olunan sınıflar manual (elle) yaratılmamış olsa dahi sonradan yeni özellikler katılabilmesini sağlamaktadır. Öyleki bu sayede koleksiyonlar, datatable, dizi gibi var olan CLR (Common Lanugage Runtime) tipleri üzerinde LINQ tarzı sorgu ifadelerinin yazılabilmesi olanaklı hale gelmiştir.
Genişletme metotları var olan tiplere ek işlevler kazandırılmasını sağlarken bunların orijinal yapısını asla bozmazlar. Tanımlandıkları programda, uygulandıkları tipin bir parçası olarak yaşar ama o tipin orijinalliğine etki etmeden ek işlevselliklerin kullanılabilmesini olanaklı kılarlar. Genişletme metodlarının oluşturulması sırasında unutulmaması gereken bir nokta bu metotların static olarak tanımlanma zorunluluğudur.
Lambda İfadeleri Lambda ifadeleri C# 3.0 ile gelen belkide en önemli özelliklerden birisidir. Bunun nedenleri arasında karmaşık işlemleri basit şekilde yazılmasına olanak sağlaması açısından yazılımcılara yararının yanı sıra LINQ konusunda da fazlasıyla kullanışlıdır.
Framework tabanlı dillerde kullanılmakta olan Lambda ifadeleri Lisp, Python gibi dillerde de bulunmaktadır. Lambda operatörü ( => ) bool sonuç döndürmekte olan bir operatördür. Lambda operatörünün neden bu kadar önemli olduğunu anlamak açısından delege (temsilci) yapısından bahsetmek daha yararlı olacaktır.
İlk zamanlardan itibaren .NET içerisinde temsilcilere yer verilmektedir. Değişkenlerin türleri olduğu gibi yordamların da kendilerine özgü türleri vardır. Bu türleri temsil eden yapılara temsilci denmektedir. Temsilciler yordamların konumlarına işaret etmektedir ve ne zaman bir yordamı kullanmak istesek temsilciler aracılığı ile onlara ulaşmak mümkün olmaktadır.
public delegate int temsilci(int carpan1, int carpan2);
public static void Main(string[] args)
{
var temsilci1 = new temsilci(carpma);
int carpim = temsilci1(3, 4);
Console.WriteLine(carpim);
}
static int carpma(int sayi1, int sayi2)
{
return sayi1 * sayi2;
}
Burada unutulmaması gereken noktalardan birisi temsilcilerin yordamların adreslerine işaret etmelerinden dolayı tanımlanan yordamlar static olmak zorundadır.
Aşağıda Lambda operatörü ile benzer işlemin ne kadar kısa yapabildiğini gösteren bir uygulama bulunmaktadır.
public delegate int toplama(int toplanan1, int toplanan2);
public static void Main(string[] args)
{
toplama islem = (x, y) => x + y;
int toplam = islem(3, 4);
Console.WriteLine(toplam);
}
Aşağıda, lambda ifadelerinin LINQ ile olan uygulamalarına geçilmeden önce kısaca LINQdan bahsedilmiştir.
LINQ (Language Integrated Query) LINQ dil ile bütünleşmiş sorgu kelimelerinin harflerinden oluşmuş bir ifadedir. Burada isminden de anlaşılacağı gibi dil içerisinde ifadeler kullanılarak yapılan sorgular akla gelmektedir. Veritabanları belki de LINQ'in isminin en çok anılmasına sebep veren alandır ama LINQ sadece veritabanı için değil daha pek çok uygulamada kullanılabilecek gelişmiş özelliklere sahiptir.
LINQ genel olarak genişletme metotları ve Lambda ifadeleri kullanmaya dayanan bir yapıdır. Farklı kullanım alanlarına göre sahip olduğu metotlar bulunmakta ve bunların belli başlıklar altında toparlanabilmesi mümkün olabilmektedir. XLINQ ve DLINQ bunlara örnek verilebilir. DLINQ veritabanı işlemlerinde kullanılan sorguların C# dili ile gerçekleştiği şeklidir. Aynı şekilde XLINQ içinde XML içeriklerinin sorgulanmasında kullanıldığından önemli bir yere sahiptir.
List<Calisan> Calisanlar = new List<Calisan>();
Calisanlar.Add(new calisan{isim = “TestOgrenci1”, no = 123});
Calisanlar.Add(new calisan{isim = “TestOgrenci2”, no = 124});
Calisanlar.Add(new calisan{isim = “TestOgrenci3”, no = 125});
Calisanlar.Add(new calisan{isim = “TestOgrenci4”, no = 126});
Calisanlar.Add(new calisan{isim = “TestOgrenci5”, no = 127});
IEnumerable<string> sonuclar = from val in calisanlar where val.no>125 orderby val.isim select val.isim.ToUpper();
var isimler = “ ” ;
foreach(string ad in sonuclar)
{
isimler += ad + “ ” ;
}
Console.WriteLine(isimler);