C#’ta çok sayıda koşul olduğunda uzun switch blokları yerine Dictionary tabanlı bir çözüm kullanmak kodu daha okunabilir ve bakımı kolay hale getirir.
// switch tabanlı yaklaşım
string GetRoleName(int roleId)
{
switch (roleId)
{
case 1: return "Admin";
case 2: return "Editör";
case 3: return "Kullanıcı";
default: return "Bilinmiyor";
}
}
// Dictionary tabanlı yaklaşım
var roles = new Dictionary<int, string>
{
{ 1, "Admin" },
{ 2, "Editör" },
{ 3, "Kullanıcı" }
};
string roleName = roles.TryGetValue(roleId, out var name)
? name
: "Bilinmiyor";
C#’ta sadece veriyi okumak ve üzerinde dolaşmak için IEnumerable<T> kullanın. Eleman eklemek, silmek veya index ile erişmek gerekiyorsa List<T> kullanın.
// Sadece okumak: üzerinde dolaşmak
IEnumerable<int> numbers = new[] { 10, 20, 30 };
foreach (var n in numbers)
{
Console.WriteLine(n);
}
// Liste: değiştirmek veya index ile erişmek
List<int> list = new List<int> { 10, 20, 30 };
list.Add(40);
Console.WriteLine(list[0]); // 10
C#’ta const değerler derleme zamanında sabittir. readonly değerler ise çalışma zamanında, genellikle constructor içinde atanabilir.
// const: derleme zamanında sabit olmalıdır
public const int MaxItems = 10;
// readonly: çalışma zamanında atanabilir
public readonly int Timeout;
public Settings()
{
Timeout = GetTimeoutFromConfig();
}
C#’ta foreach döngüsü içinde koleksiyonu değiştirmek çalışma zamanı hatasına yol açar. Değişiklik gerekiyorsa önce kopya üzerinde dolaşılmalıdır.
// Bu kullanım hata oluşturur
foreach (var item in items)
{
items.Remove(item);
}
// Güvenli yaklaşım: kopya üzerinde dolaşmak
foreach (var item in items.ToList())
{
items.Remove(item);
}
// Alternatif: for döngüsü kullanmak
for (int i = items.Count - 1; i >= 0; i--)
{
items.RemoveAt(i);
}
C#’ta nesneler kimliklerine göre değerlendiriliyorsa class, değerlerine göre değerlendiriliyorsa record kullanılmalıdır.
// class: kimlik odaklı
class User
{
public string Name { get; set; }
public int Age { get; set; }
}
var u1 = new User { Name = "Ali", Age = 30 };
var u2 = new User { Name = "Ali", Age = 30 };
Console.WriteLine(u1 == u2); // False
// record: değer odaklı
record UserRecord(string Name, int Age);
var r1 = new UserRecord("Ali", 30);
var r2 = new UserRecord("Ali", 30);
Console.WriteLine(r1 == r2); // True
C#’ta ?. operatörü, bir nesnenin değeri yoksa (null) hata oluşturmadan güvenli şekilde özellik veya metoda erişmeyi sağlar.
Person? person = null;
// Eski kullanım
string name1 = person != null ? person.Name : null;
// Önerilen kullanım
string? name2 = person?.Name;
Console.WriteLine(name1); // null
Console.WriteLine(name2); // null
C#’ta is ve is not ile daha okunabilir tür kontrolleri ve desen eşleştirmeleri yapabilirsiniz.
// Eski kullanım (as ve null kontrolü)
object obj = "Merhaba, dünya!";
if (obj is string)
{
Console.WriteLine(((string)obj).ToUpper()); // MERHABA, DÜNYA!
}
// Önerilen kullanım (is ile)
if (obj is string str)
{
Console.WriteLine(str.ToUpper()); // MERHABA, DÜNYA!
}
// Negasyon için "is not" kullanımı
if (obj is not int)
{
Console.WriteLine("Bir tam sayı değil");
}
C#’ta string karşılaştırması yaparken == yerine StringComparison kullanmak kültüre ve büyük/küçük harfe bağlı hataları önler.
string a = "istanbul";
string b = "İSTANBUL";
// Yanlış / riskli
bool eq1 = a == b;
// Doğru yaklaşım
bool eq2 = string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
Console.WriteLine(eq1); // False
Console.WriteLine(eq2); // True
C#’ta null-coalescing (??) operatörü, bir değer null ise varsayılan bir değer atamayı sağlar.
string? userName = null;
// Eski kullanım
string name1 = userName != null ? userName : "Misafir";
// Önerilen kullanım
string name2 = userName ?? "Misafir";
Console.WriteLine(name1); // Misafir
Console.WriteLine(name2); // Misafir
C#’ta String.Format yerine string interpolation ($"...") kullanmak kodu daha okunabilir ve güvenli hale getirir.
int a = 18, b = 22;
string text;
// Eski kullanım
text = string.Format("number1: {0}, number2: {1}", a, b);
// Önerilen kullanım
text = $"number1: {a}, number2: {b}";