Kod geliştirme verimliliğinizi arttıracak ve hız katacak C# ipuçları

(?) Koşula bağlı değenlendirme operatörü

Bu operatör bize if-then-else pattern’ini tek bir satırda yapmamıza olanak sağlar. Bu öperatörü kullanmadan yazacağımız örnek kodlar aşağıdaki gibi olacaktır.

int a = 10;
int b = 20;
int max;

if (a > b)
  max = a;
else
  max = b;

Operatörün kullandıktan sonra kodlarımızın ne kadar kısaldığını gözlemleyelim.
Kullanım şekli (Koşul) ? Doğru cevap : Yanlış cevap

int a = 10;
int b = 20;
int max = (a > b) ? a : b;


Null-Coalesce operatörü (??)

Kodunuzda null değerleri ne sıklıkla kontrol ediyorsuz? Sıkça mı? O zamansa null-coalesce operatörü (??) size çok kullanışlı gelecektir.
Aşağıdaki örnekle operetörün nasıl çalıştığını gözlemleyelim :

object c= null;
object d = new object();
object e;

if (c != null)
    e = c;
else
   e = d;

Bunu kodu yukarıda bahsettiğimiz (?) koşula bağlı değenlendirme operatörü ile tek satıra indirgeyebiliriz :

object c= null;
object d = new object();
object e = (c != null) ? c : d;

Ama null-coalesce operatörünü (??) kullanarak daha da kısa ve kullanışlı hale getirebiliriz. Eğer sol taraftaki değişken boş işe sağ taraftaki değişkenimiz kullanılacaktır.

object c= null;
object d = new object();
object e = c ?? d;

Object (Initializers) başlatıcılar

Bir obje oluşturduğumuzda sıklıkla bir veya daha fazla özelliğini set ederiz. C# 3.0 ile gelen object (initializers) başlatıcıları ile bu yeni oluşturduğumuz objelerin özelliklerini daha kolay bir biçimde set edebilir hale geldik. Bu şekilde daha okunabilir ve daha az kod yazarak obje oluşturabilir ve özelliklerini set edebiliriz.

Customer c = new Customer();
c.Name = "Bora";

c.Address = "Mimar Kemalettin Caddesi No:2";

Yukarıdaki gibi oluşturup sonrasında özelliklerini set etmek yerine daha objeyi oluştururken set edebiliriz :

Customer c = new Customer { Name="Bora", Address = "Mimar Kemalettin Caddesi No:2" };

Using ifadesi

Dosya, network yada font gibi bir sistem kaynağını kullanmak isteğimizde; ayarlamamız gereken üç nokta vardır kaynağı ayırmak, kullanmak ve sonrasında dispose etmek. Eğer kullandığımız sistem kaynaklarını düzgün bir biçimde dispose etmez isek memory problemleri ortaya çıkar. Bu durumu önlemek için dispose pattern’i yada using ifadesi kullanırız :

     // 1. Kaynağı ayırdık
    Stream stream = null;
    try
    {
       stream = File.OpenRead(@"c:\test\test.txt");
    // 2. Kaynağımızı kullandığımız kodlar
    }
    finally
    {
     // 3. Kaynağımızı dispose ettik
       if (stream != null) stream.Dispose();
    }

Using ifadesini kullandığımız durum :


    // Kaynağı ayırdık
    using (Stream stream = File.OpenRead(@"c:\test\test.txt"))
    {
       // Kaynağımızı kullandığımız kodlar
    }
    // Otomatik dispose

    // Birden fazla kaynak oluşturup aynı using ifadesi içerisinde de kullanılabilir.
    using (Stream stream = File.OpenRead(@"c:\test\test.txt"), stream2 = File.OpenRead(@"c:\test\test2.txt"))
    {
       // Kaynaklarımızı kullandığımız kodlar
    }
    // Otomatik dispose

Using ifadesi “IDisposable” interface’ini implement etmiş tüm objeler için kullanılabilir.

Uzun namaspace’ler ve tipler için Aliases kullanımı

C# içerisinde tanımlayıcılar bazen uzun olabilmektedir eğer bir de Microsoft Office uygulaması geliştiriyorsanız. Böyle bir durumda alias kullanarak kod içerisinde yazım kolaylığı sağlayabiliriz.

using Word = Microsoft.Office.Interop.Word;
...
Word.Application = new Word.Application() { Visible = True; }

Nullable objects

Tanımladığımız bir değişkenin değeri olmak zorundadır ancak bazen oluşturduğunuz değişkenlere “null” değeri atayabilmek kullanışlı olabilmektedir. .Net 2.0 ile gelen Nullablegeneric sayesinde değişkenlere “null” değerini atayabilmekteyiz.

Aşağıdaki kullanımı incelediğimizde oluşturulan objeler birbirinin aynısıdır:

Nullable<int> x = null;
int? x = null;

Değişken tanımlarken önüne ? konulduğunda compiler Nullable<T> generic tipi ile tanımlama yapılmış gibi davranmaktadır.

Automatic Properties

Sınıf içerisinde private olarak tanımladığımız bir değişkeni dış dünyada kullanıma açmak için ekstra public property yazmamız gerekiyordu. Ancak C# 3.0 ile gelen automatic property’ler sayesinde bu durum otomatize edilip daha basit bir hale indirgendi :

public class Person
{
 private string _firstName;
 public string FirstName
 {
    get { return _firstName; }
    set { _firstName = value; }
 }
}

Automatic property kullandığımızda ise kodumuz aşağıdaki gibi olacaktır:

public class Person
{
 public string Firstname { get; set; }
}

C# compiler’ı otomatik olarak arka tarafta bir değişken oluşturup uygun get ve set atamasını yapmaktadır. Uzun uzadıya kod yazmak yerine compiler bu işlemi bizim yerimize yapmış oldu.

(Type inference) Tip çıkarsama

C# içerisinde tipik olarak tanımlama yaparken yazdıklarımıza dikkat ederiz:

string str= “Merhaba Dünya”;

Aşağıdaki koda baktığımızda sağ tarafta atanan değerin string olduğu ortadadır ama compiler bunu kendi çözümlemektedir.

var str= “Hello World”;

Böyle bir kullanımda string tipinde olan “str” değişkeni oluşturulacaktır ve compiler veri tipini compile zamanı otomatik olarak çözümleyecektir.

var SeniorStaff = Employees.Where(s => s.Age > 35);
foreach(var Member in SeniorStaff)
           Console.WriteLine("Name: {0} Age: {1}",Member.Name,Member.Age);

Peki yukarıdaki gibi bir kullanımda SeniorStaff’ın türü ne olacaktır?

((System.Linq.Enumerable.Iterator<<>f__AnonymousType0>)(SeniorStaff))

Böyle bir durumda compiler yine otomatik olarak bizim yerimize tip çözümleme işlemini yapmış oldu ve Anonymous Type olarak belirledi. Anonymous Tiplerle ilgili yazımda bu tiplere daha detaylı değineceğim.

string.IsNullOrEmpty

Eğer sıklıkla string değişkenlerin boş yada null olduğununu kontrol ediyorsanız string.IsNullOrEmpty metodu size kullanışlı gelebilir. Kontrol ettiğiniz değişken boş yada null ise metod true değerini döndürecektir.

if (String.IsNullOrEmpty(s))
    return "null yada empty değer.";
else
     return String.Format("(\"{0}\") kontrol ettiğiniz değer null yada empty değildir.", s);

Lambda İfadeleri (Expressions)

C# 2.0 ile hayatımıza giren anonymous metodlar, metod içerisine metod tanımlamanıza olanak sağlayan yapılardır. Oldukça güçlü olan ve lojik işlemlerinizi kod içerisinde kolayca gerçekleştirmemizi sağlamasına karşın okunabilirliği biraz zordur.

Func mySeniorStaffFilter = delegate(int a) { return a > 35; };

Yukarıdaki metoda baktığımızda integer bir parametre almakta ve boolean bir değer geri döndürmektedir. Lambda ifadeleri sayesinde yukarıda yazdığımız metodu okuması daha kolay bir biçimde yazabiliriz :

Func mySeniorStaffFilter = a => a > 35;

Hatta lambda ifaderi bu delegate yapısına uyan diğer tüm yerlerde de kullanabiliriz.

var SeniorStaff = Employees.Where(s => s.Age > 35);

C# 4.0 ile gelen optional ve named (arguments) parametreler

C# 4.0 ile gelen bonus özelliklerden biride optional ve named parametrelerdir. Optional ve named parametreler sayesinde metod parametrelerine default bir değer atayabilir yada parametrelerin sırasına dikkat etmeden istediğimiz parametreye değer gönderebiliriz.

Named Arguments:

class NamedExample
{
    static void Main(string[] args)
    {
        // Metod normal şekilde çağrılmıştır. (positional arguments)
        Console.WriteLine(CalculateBMI(123, 64));

        // Aşağıdaki kullanım Named arguments yardımıyla sıranın önemi olmadan kullanılmıştır.
        Console.WriteLine(CalculateBMI(weight: 123, height: 64));
        Console.WriteLine(CalculateBMI(height: 64, weight: 123));

        // Positional argument'lar ile named argument'lar ile parametre sırası bozularak birlikte kullanılamaz.
        // Aşağıdaki ifade compile error verecektir.
        //Console.WriteLine(CalculateBMI(weight: 123, 64));

        // Positional argument'lar ile named argument'lar ile parametre sırası bozulmadan birlikte kullanılabilir.
        Console.WriteLine(CalculateBMI(123, height: 64));
    }

    static int CalculateBMI(int weight, int height)
    {
        return (weight * 703) / (height * height);
    }
}

Optional Arguments :

//Opsiyonel parametrelere bir değer atanmadığında default olarak atanan değer kabul edilerek işlem yapılır.
public void ExampleMethod(int required, string optionalstr = "default string")

Kaynak;

Named and Optional Arguments (C# Programming Guide)

Martijn’s C# Programming Blog

Bir cevap yazın