Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Generics, tip belirtilmeden çalışabilen ve kodunuzu daha esnek ve yeniden kullanılabilir hale getiren bir özelliktir. Bu, bir sınıfın veya metotun çalışma zamanında hangi veri türleriyle kullanılacağını belirtmediği anlamına gelir. Bunun yerine, kullanıcıya, hangi türleri kullanacaklarını belirleme özgürlüğü tanır.
public class GenericClass<T>
{
private T _genericField;
public GenericClass(T genericParameter)
{
_genericField = genericParameter;
}
public T GenericMethod(T input)
{
//...
return input;
}
}
Generic Sınıflar:
// Generic Stack sınıfı örneği
public class Stack<T>
{
private List<T> items = new List<T>();
public void Push(T item)
{
items.Add(item);
}
public T Pop()
{
if (items.Count == 0)
throw new InvalidOperationException("Stack is empty");
T item = items[items.Count - 1];
items.RemoveAt(items.Count - 1);
return item;
}
}
Generic Metotlar:
// Generic bir metot örneği
public T FindMax<T>(T first, T second) where T : IComparable<T>
{
return first.CompareTo(second) > 0 ? first : second;
}
List<T>:
List<int> numbers = new List<int>();
Dictionary<TKey, TValue>:
Dictionary<string, int> ageMap = new Dictionary<string, int>();
Queue<T>:
Queue<double> queue = new Queue<double>();
Stack<T>:
Stack<bool> stack = new Stack<bool>();
Generics kullanırken bazı kısıtlamalara dikkat etmek önemlidir. Kısıtlamalar, generic tiplerin belirli kurallara uymasını sağlar.
public class GenericClass<T> where T : class
{
// T, referans tip olmalı
}
Generics, çalışma zamanında tip belirleme işlemini gerçekleştirdiği için performans açısından avantajlıdır. Bu, generic tiplerin kullanımı sırasında tip dönüşümleri gerektiğinde, bu dönüşümlerin daha verimli bir şekilde yapılabileceği anlamına gelir.
Generics, C# dilinde güçlü bir programlama özelliğidir ve özellikle koleksiyon sınıfları, LINQ operatörleri ve tasarım desenleri gibi birçok yerde kullanılır. İleri düzey C# konseptlerini anlamak ve teknik mülakatlara hazırlanmak isteyenler için Generics, bilgi düzeyinizi artırmanızı sağlayacak önemli bir konudur.
Delegate, C# dilinde bir metodun referansını saklayan ve bu metodu çağırabilen bir türdür. Delegates, olay tabanlı programlamada ve asenkron işlemlerde kullanılarak kodun daha modüler ve esnek olmasını sağlar.
// Delegate tanımı
public delegate void MyDelegate(string message);
// Delegate kullanımı
MyDelegate myDelegate = SomeMethod;
myDelegate("Hello, delegates!");
// Metot imzasına uygun bir metot
static void SomeMethod(string message)
{
Console.WriteLine(message);
}
Olay Tabanlı Programlama:
public class Button
{
public delegate void ClickHandler(object sender, EventArgs e);
public event ClickHandler Click;
public void OnClick()
{
Click?.Invoke(this, EventArgs.Empty);
}
}
Asenkron Programlama:
public delegate void AsyncOperation();
public class AsyncExample
{
public void PerformAsyncOperation(AsyncOperation operation)
{
// Asenkron operasyonu başlat
IAsyncResult result = operation.BeginInvoke(null, null);
// Ana iş parçası devam edebilir
Console.WriteLine("Main thread continues...");
// Asenkron operasyonun tamamlanmasını bekle
operation.EndInvoke(result);
}
}
LINQ ve Lambda İfadeleri:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// LINQ sorgusu ile delegate kullanımı
var evenNumbers = numbers.Where(n => n % 2 == 0);
event
anahtar kelimesi ile birleştirildiğinde, sadece += ve -= operatörleri kullanılarak olaylara abone olunabilir veya abonelikten çıkılabilir.public class Button
{
public delegate void ClickHandler(object sender, EventArgs e);
public event ClickHandler Click;
public void OnClick()
{
Click?.Invoke(this, EventArgs.Empty);
}
}
Action
ve Func
geneldelegates türleridir. Action
, geri dönüş değeri olmayan metotları temsil ederken, Func
bir geri dönüş değeri olan metotları temsil eder.// Action delegate örneği
Action<string> action = Console.WriteLine;
action("Hello, Action!");
// Func delegate örneği
Func<int, int, int> add = (a, b) => a + b;
int result = add(5, 3); // result = 8
public class ClosureExample
{
public Action<int> CreateClosure()
{
int outerVariable = 10;
// Closure kullanımı
Action<int> closure = x =>
{
int result = x + outerVariable;
Console.WriteLine(result);
};
return closure;
}
}
Delegates, C# dilinde güçlü ve esnek bir özelliktir ve olay tabanlı programlamadan asenkron işlemlere kadar birçok alanda kullanılır. Derinlemesine bir anlayış, bu konsepti etkili bir şekilde kullanmanıza yardımcı olabilir ve teknik mülakatlarda başarıya giden yolda önemli bir adım olabilir.
Lambda ifadeleri, C# dilinde anonim fonksiyonları ifade etmek için kullanılan kısa ve kompakt bir sözdizimidir. Genellikle LINQ sorgularında, olay dinleyicilerinde ve daha birçok yerde kullanılırlar.
// Parametre almayan ve bir değer döndürmeyen lambda ifadesi
Action sayHello = () => Console.WriteLine("Hello, Lambda!");
// Bir parametre alan ve bir değer döndüren lambda ifadesi
Func<int, int> square = x => x * x;
// Birden fazla parametre alan ve bir değer döndüren lambda ifadesi
Func<int, int, int> add = (a, b) => a + b;
LINQ Sorguları:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Lambda ifadesi ile LINQ sorgusu
var evenNumbers = numbers.Where(n => n % 2 == 0);
Olay Dinleyicileri:
button.Click += (sender, e) =>
{
Console.WriteLine("Button clicked!");
};
Task ve Async İşlemler:
Task.Run(() =>
{
Console.WriteLine("Task is running...");
});
Filtreleme ve Dönüştürme İşlemleri:
List<string> words = new List<string> { "apple", "banana", "cherry" };
// Lambda ifadesi ile filtreleme
var result = words.Where(word => word.Length > 5).Select(word => word.ToUpper());
Lambda ifadeleri, genellikle delegates türleri ile birlikte kullanılır. Önceki bölümde anlatılan delegates konsepti ile birlikte, aynı işlevi ifade etmek için lambda ifadelerini kullanabilirsiniz.
// Delegate tanımı
public delegate int Calculate(int x, int y);
// Lambda ifadesi ile delegates kullanımı
Calculate add = (a, b) => a + b;
Calculate multiply = (a, b) => a * b;
Lambda ifadeleri, closure konsepti ile birlikte kullanıldığında dışarıdaki değişkenlere erişebilir. Bu, lambda ifadelerini daha esnek ve güçlü kılar.
public class ClosureExample
{
public Action<int> CreateClosure()
{
int outerVariable = 10;
// Lambda ifadesi ile closure kullanımı
Action<int> closure = x =>
{
int result = x + outerVariable;
Console.WriteLine(result);
};
return closure;
}
}
Lambda ifadeleri, LINQ sorgularının temelini oluşturur. LINQ, veri koleksiyonlarını sorgulamak ve işlemek için lambda ifadelerini kullanır.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Lambda ifadesi ile LINQ sorgusu
var evenNumbers = numbers.Where(n => n % 2 == 0);
Lambda ifadeleri, Task ve asenkron programlama konseptleriyle birlikte kullanılarak paralel ve asenkron işlemler oluşturmak için kullanılabilir.
// Lambda ifadesi ile asenkron operasyon
Task.Run(() =>
{
Console.WriteLine("Task is running...");
});
Lambda ifadeleri, Func ve Action gibi geneldelegates türleriyle birlikte kullanılarak kısa ve anlamlı bir şekilde işlev sağlar.
// Action delegate örneği
Action<string> action = message => Console.WriteLine(message);
action("Hello, Lambda!");
// Func delegate örneği
Func<int, int, int> add = (a, b) => a + b;
int result = add(5, 3); // result = 8
Lambda ifadeleri, C# dilinde kodunuzu daha kısa ve işlevsel hale getirmek için güçlü bir araçtır. LINQ sorgularından olay dinleyicilerine, asenkron programlamadan delegates kullanımına kadar birçok alanda kullanılırlar. Bu konsepti anlamak, kodunuzu daha modern ve okunabilir hale getirmenize yardımcı olabilir.
Events, bir sınıfın içinde meydana gelen önemli durumları veya olayları bildirmek ve bu olaylara tepki göstermek için kullanılan bir C# dil özelliğidir. Bu, sınıfın dışındaki diğer sınıfların veya bileşenlerin bu olaylara abone olmasını sağlar.
// Delegate tanımı
public delegate void EventHandler(object sender, EventArgs e);
// Event tanımı
public class MyClass
{
public event EventHandler MyEvent;
// Olayı tetikleyen bir metot
protected virtual void OnMyEvent()
{
MyEvent?.Invoke(this, EventArgs.Empty);
}
}
public class EventSubscriber
{
public void Subscribe(MyClass myObject)
{
// Event'e abone olma
myObject.MyEvent += HandleEvent;
}
private void HandleEvent(object sender, EventArgs e)
{
Console.WriteLine("Event handled!");
}
}
EventHandler
delegesi kullanarak standart olaylar.EventHandler<TEventArgs>
delegesi kullanarak generic olaylar.public
, private
, protected
, internal
) uygulanabilir, bu da olayların hangi kapsamda erişilebileceğini kontrol etmenizi sağlar.public class MyClass
{
// Sadece aynı sınıf içinde erişilebilir olay
private event EventHandler MyPrivateEvent;
// Herkes tarafından erişilebilir olay
public event EventHandler MyPublicEvent;
}
+=
ve -=
operatörlerini kullanarak abone olma ve abonelikten çıkma gibi özel operasyonları destekler.public class MyClass
{
// Delegate tanımı
public delegate void MyDelegate();
// Event tanımı
public event MyDelegate MyEvent;
public void TriggerEvent()
{
// Olayı tetikleme
MyEvent?.Invoke();
}
}
+=
operatörü ile).-=
operatörü ile).EventArgs
sınıfından türetilmiş özel sınıflar kullanılır.public class MyEventArgs : EventArgs
{
public string EventMessage { get; set; }
}
public class MyClass
{
public event EventHandler<MyEventArgs> MyEvent;
protected virtual void OnMyEvent(string message)
{
MyEvent?.Invoke(this, new MyEventArgs { EventMessage = message });
}
}
protected
veya public
olmalı ve olayı tetiklemek için protected virtual
bir metot kullanılmalıdır.public class MyClass
{
// Olay tanımı
public event EventHandler MyEvent;
// Olayı tetikleyen metot
protected virtual void OnMyEvent()
{
MyEvent?.Invoke(this, EventArgs.Empty);
}
}
GetInvocationList()
metodu kullanılabilir.public class MyClass
{
// Olay tanımı
public event EventHandler MyEvent;
// Olayı tetikleyen metot
protected virtual void OnMyEvent()
{
MyEvent?.Invoke(this, EventArgs.Empty);
// Abone olan nesne sayısını kontrol etme
int subscriberCount = MyEvent?.GetInvocationList().Length ?? 0;
Console.WriteLine($"Number of subscribers: {subscriberCount}");
}
}
Olaylar (Events), C# dilinde olay tabanlı programlamada önemli bir rol oynarlar. Bu konsepti anlamak, bir sınıfın dışındaki diğer bileşenlere nasıl olaylar bildireceğinizi ve bu olaylara nasıl tepki vereceğinizi öğrenmenize yardımcı olur. Olaylar, GUI programlamadan asenkron işlemlere kadar birçok alanda kullanılır ve C# dilinde yazılım geliştirme pratiğinde önemli bir yer tutar.
Extension Methods, C# dilinde bir sınıfın yeteneklerini genişleten, ancak sınıfın kendisini değiştirmeyen bir dil özelliğidir. Bu sayede, özellikle framework sınıflarına veya sealed sınıflara yeni metotlar eklemek mümkün olur.
public static class StringExtensions
{
// Extension method tanımı
public static string CustomExtensionMethod(this string input)
{
// Metot içeriği
return "Modified: " + input;
}
}
// Extension method'u kullanma
string originalString = "Hello, Extension Methods!";
string modifiedString = originalString.CustomExtensionMethod();
Console.WriteLine(modifiedString);
// Static metot kullanımı
string modifiedString = StringExtensions.CustomExtensionMethod(originalString);
// Nullable türü üzerinde extension method kullanımı
int? nullableNumber = 42;
string result = nullableNumber.CustomExtensionMethod(); // Dikkat: NullReferenceException olabilir!
public static class ListExtensions
{
// Generic tür üzerinde extension method tanımı
public static T LastOrDefault<T>(this List<T> list)
{
if (list.Count > 0)
return list[list.Count - 1];
else
return default;
}
}
// LINQ sorgusu ile extension method kullanımı
var evenNumbers = numbers.Where(n => n % 2 == 0);
public interface ILogger
{
void Log(string message);
}
public static class LoggerExtensions
{
// ILogger interface'i üzerinde extension method tanımı
public static void LogError(this ILogger logger, string errorMessage)
{
logger.Log($"Error: {errorMessage}");
}
}
public sealed class SealedClass
{
public int Value { get; set; }
}
public static class SealedClassExtensions
{
// Sealed sınıf üzerinde extension method tanımı
public static void PrintValue(this SealedClass sealedObj)
{
Console.WriteLine(sealedObj.Value);
}
}
// Naming convention örneği
public static class StringExtensions
{
public static string ToCustomFormat(this string input)
{
// Metot içeriği
return "Custom Format: " + input;
}
}
// Extension method'u kullanma için gerekli using direktifi
using MyExtensionsNamespace;
// Extension method'u kullanımı
string modifiedString = originalString.CustomExtensionMethod();
// LINQ Fluent Syntax ile extension method kullanımı
var result = numbers
.Where(n => n % 2 == 0)
.OrderByDescending(n => n)
.Take(3);
public static class IntExtensions
{
// Geriye değer döndüren extension method tanımı
public static bool IsEven(this int number)
{
return number % 2 == 0;
}
}
// Dikkat: Her çağrıldığında yeni bir StringBuilder örneği oluşturulur!
string result = "Hello".CustomExtensionMethod();
Extension Methods, C# dilinde mevcut sınıflara veya türlere yeni metotlar eklemek için güçlü bir araçtır. Bu özellik, özellikle framework sınıfları üzerinde değişiklik yapmadan genişletmeler yapmanıza olanak tanır. Ancak dikkatli kullanılmalıdır çünkü yanlış kullanım performans sorunlarına yol açabilir.
LINQ, C# diline entegre edilmiş bir sorgu dilidir. Bu dil, veri koleksiyonları üzerinde sorgular oluşturmayı, verileri filtrelemeyi, sıralamayı ve dönüştürmeyi sağlar. LINQ sayesinde veritabanlarına, XML dosyalarına, koleksiyonlara ve diğer veri kaynaklarına yönelik sorgular daha kolay ve okunabilir hale gelir.
LINQ, iki temel sözdizim sunar: Sorgu Sözdizimi (Query Syntax) ve Metot Sözdizimi (Method Syntax).
var result = from student in students
where student.Age > 18
orderby student.LastName
select student;
var result = students
.Where(student => student.Age > 18)
.OrderBy(student => student.LastName);
LINQ sorguları, genellikle Lambda Expressions ile birleştirilir. Lambda Expressions, sorguların içinde koşullar, projeksiyonlar ve diğer ifadeler için kullanılır.
var result = students
.Where(student => student.Age > 18)
.OrderBy(student => student.LastName)
.Select(student => new { FullName = $"{student.FirstName} {student.LastName}", student.Age });
LINQ, farklı veri tipleri üzerinde çalışabilir. Bunlar arasında:
LINQ sorguları genellikle “Deferred Execution” (Erteleme Yürütme) prensibini takip eder. Bu, bir LINQ sorgusunun, sonuçlarına ilk kez erişildiğinde gerçekleştirilmesi anlamına gelir. Bu, performansı artırabilir çünkü sorgu sonuçlarına ihtiyaç duyulana kadar hesaplanmaz.
Bazı durumlarda, LINQ sorgusunun hemen çalıştırılmasını isteyebilirsiniz. Bu durumda, ToList
, ToArray
, ToDictionary
gibi metotlar kullanılır.
var result = students
.Where(student => student.Age > 18)
.OrderBy(student => student.LastName)
.ToList(); // Hemen çalıştırma
LINQ sorguları genellikle anonymous types ile çalışır. Bu, sorgunun sonucunda özel bir veri tipi oluşturmadan doğrudan veriye erişmeyi sağlar.
var result = from student in students
where student.Age > 18
select new { student.FirstName, student.LastName };
LINQ sorgularında null kontrollerine dikkat edilmelidir. Özellikle, veritabanı sorgularında null değerlere karşı güvenli bir şekilde işlem yapmak önemlidir.
var result = students
.Where(student => student != null && student.Age > 18)
.OrderBy(student => student?.LastName)
.Select(student => new { FullName = $"{student?.FirstName} {student?.LastName}", student?.Age });
GroupJoin, iki koleksiyon arasında birleştirme yaparken bir gruplama yapılmasını sağlar.
var result = departments
.GroupJoin(employees, department => department.Id, employee => employee.DepartmentId, (department, employeeGroup) =>
new
{
DepartmentName = department.Name,
Employees = employeeGroup.Select(employee => $"{employee.FirstName} {employee.LastName}")
});
Query Syntax, aslında arka planda Method Syntax’e çevrilen bir şeker sözdizimidir. Yani, her iki sözdizimi de aynı işlevi yerine getirir.
LINQ, Entity Framework ile entegre bir şekilde çalışır ve veritabanı sorgularını nesne sorgularına dönüştürerek veritabanı işlemlerini kolaylaştırır.
var result = dbContext.Customers
.Where(customer => customer.Orders.Any(order => order.TotalAmount > 1000))
.OrderBy(customer => customer.LastName)
.ToList();
LINQ (Language-Integrated Query), C# dilini daha güçlü ve okunabilir hale getiren bir özelliktir. Veritabanı sorgularını, XML işlemlerini ve diğer veri manipülasyonlarını kolaylaştırır. LINQ, geniş bir veri yelpazesinde çalışabilir ve C# geliştiricilerine daha etkili ve hızlı kod yazma imkanı sunar.
Nullable Types, normalde null alamayan değer tiplerine (int
, double
, bool
, vb.) null değeri atamayı sağlayan bir dil özelliğidir. Bu, özellikle veritabanlarından gelen verilerle çalışırken veya bir değerin eksik olabileceği senaryolarda kullanışlıdır.
// Nullable bir integer tanımı
int? nullableInt = null;
// Nullable bir boolean tanımı
bool? nullableBool = true;
// Nullable bir double tanımı
double? nullableDouble = 3.14;
int?
, double?
, bool?
gibi nullable versiyonları mevcut değer tipleriyle aynı işlevi görür.int? nullableInt = null;
int regularInt = 42;
// Nullable bir değeri, normal bir değere atanabilir
regularInt = nullableInt ?? 0; // Eğer nullableInt null ise, 0 olarak atanır
??
), nullable bir değeri kontrol eder ve değer null ise belirli bir varsayılan değeri atar.int? nullableInt = null;
int result = nullableInt ?? 0; // Eğer nullableInt null ise, 0 olarak atanır
HasValue
özelliği, nullable bir değerin null olup olmadığını kontrol eder.int? nullableInt = null;
if (nullableInt.HasValue)
{
Console.WriteLine($"Value: {nullableInt.Value}");
}
else
{
Console.WriteLine("Value is null");
}
GetValueOrDefault
metodu, nullable bir değerin değerini alır, ancak eğer null ise varsayılan bir değer döndürür.int? nullableInt = null;
int result = nullableInt.GetValueOrDefault(-1); // Eğer nullableInt null ise, -1 olarak atanır
?.
), bir nesnenin veya değerin null olup olmadığını kontrol eder ve null ise bir hata almaz.int? nullableInt = null;
string result = nullableInt?.ToString(); // Eğer nullableInt null ise, result null olur, hata almaz
List<int?> numbers = new List<int?> { 1, 2, null, 4, 5 };
var result = numbers
.Where(num => num.HasValue && num.Value > 2)
.Select(num => num.GetValueOrDefault())
.ToList();
int? nullableInt = 42;
string message = nullableInt switch
{
null => "Value is null",
0 => "Value is zero",
var value when value > 0 => "Value is positive",
_ => "Value is negative"
};
// Veritabanından gelen bir alanı temsil eden nullable bir property
public int? Age { get; set; }
var result = dbContext.Users
.Where(user => user.Birthdate.HasValue)
.ToList();
// Bellek kullanımını artırabilir
int? nullableInt = null;
// Bu property'nin bilinçli olarak null olabileceğini belirtmek
public int? NullableProperty { get; set; }
// Nullable bir property'nin null olma durumunu kontrol etme
if (nullableInt.HasValue)
{
// Güvenli bir şekilde nullableInt.Value kullanabilirsiniz
int result = nullableInt.Value * 2;
}
Nullable Types, C# dilinde değer tiplerine null değeri atama yeteneği kazandıran ve özellikle veritabanı entegrasyonu gibi senaryolarda kullanışlı olan bir dil özelliğidir. Bu özellik, kodun okunabilirliğini artırır, kod güvenliğini artırır ve belirli senaryolarda daha esnek bir programlama yaklaşımı sunar.
Dynamic, C# dilinde bir türdür. Ancak, derleme zamanında türü belirlenmez; bunun yerine, çalışma zamanında belirlenir. Bu, C# dilinde normalde statik olarak tür belirlenen bir dil özelliği ile çalışmak yerine, dinamik olarak tür belirleme ihtiyacı olan durumlar için kullanışlıdır.
dynamic dynamicVariable = 42;
Console.WriteLine(dynamicVariable); // Çalışma zamanında tür belirlenir
dynamicVariable = "Hello, Dynamic!";
Console.WriteLine(dynamicVariable); // Yeni tür, çalışma zamanında belirlenir
var
, derleme zamanında türünü belirler, ancak dynamic
çalışma zamanında belirler. var
ve dynamic
arasındaki fark, özellikle tür bilgisinin ne zaman alındığına bağlıdır.// Veritabanından gelen bir sonucu temsil eden dynamic
dynamic result = GetFromDatabase();
Console.WriteLine(result.Name);
Console.WriteLine(result.Age);
dynamic comObject = GetComObject();
comObject.Method(); // Çalışma zamanında tür belirlenir
dynamic expando = new ExpandoObject();
expando.Name = "John";
expando.Age = 30;
Console.WriteLine(expando.Name);
public class CustomDynamic : DynamicObject
{
private Dictionary<string, object> properties = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return properties.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
properties[binder.Name] = value;
return true;
}
}
dynamic customDynamic = new CustomDynamic();
customDynamic.Name = "Alice";
Console.WriteLine(customDynamic.Name);
dynamic dynamicNumber = 42;
int intNumber = dynamicNumber; // Çalışma zamanında tür dönüşümü
dynamic result = GetResult();
Console.WriteLine(result.Property); // Bu noktada Property'nin türü hakkında bilgi yok
dynamic dynamicVariable = 42;
string result = dynamicVariable.Method(); // Çalışma zamanında hata alınabilir
dynamic dynamicNullable = null;
int? nullableInt = dynamicNullable;
var dynamicQuery = dbContext.Customers
.Where(customer => customer.Name.StartsWith("A"))
.Select(customer => new { customer.Id, customer.Name });
dynamic result = GetResult();
Assert.IsNotNull(result);
Dynamic, C# dilinde tür bilgisini çalışma zamanında belirleme yeteneği sunan bir özelliktir. Özellikle belirli durumlarda, örneğin COM Interop veya veritabanı entegrasyonu sırasında, dynamic kullanımı avantajlı olabilir. Ancak, yanlış kullanıldığında kod karmaşıklığına ve güvenlik sorunlarına yol açabilir. Bu nedenle, dynamic kullanımı ihtiyatlı bir şekilde yapılmalı ve kodun okunabilirliği ile performans etkisi dikkate alınmalıdır.
Exception (İstisna), bir uygulama çalıştığında ortaya çıkan beklenmeyen durumları temsil eden bir nesnedir. Bu durumlar, programın normal akışını kesintiye uğratan ve genellikle hataları belirten durumlardır.
try
{
// Hata olasılığı bulunan kod bloğu
}
catch (Exception ex)
{
// Hata oluştuğunda çalışacak kod bloğu
Console.WriteLine($"Hata Mesajı: {ex.Message}");
}
finally
{
// Her durumda çalışacak kod bloğu (isteğe bağlı)
}
try
{
// Hata olasılığı bulunan kod bloğu
}
catch (DivideByZeroException ex) // Belirli bir hata türü için
{
Console.WriteLine($"Bölme Hatası: {ex.Message}");
}
catch (InvalidOperationException ex) // Başka bir hata türü için
{
Console.WriteLine($"Geçersiz İşlem Hatası: {ex.Message}");
}
catch (Exception ex) // Genel hata durumu için
{
Console.WriteLine($"Bir hata oluştu: {ex.Message}");
}
finally
bloğu, try-catch bloklarının sonunda yer alır ve her durumda çalışacak kodları içerir.try
{
// Hata olasılığı bulunan kod bloğu
}
catch (Exception ex)
{
// Hata oluştuğunda çalışacak kod bloğu
Console.WriteLine($"Hata Mesajı: {ex.Message}");
}
finally
{
// Her durumda çalışacak kod bloğu
Console.WriteLine("Finally bloğu çalıştı");
}
throw
anahtar kelimesi, belirli bir hata durumunu kodun içinde oluşturmak için kullanılır.int age = -1;
try
{
if (age < 0)
{
throw new ArgumentException("Yaş negatif olamaz.");
}
}
catch (ArgumentException ex)
{
Console.WriteLine($"Hata: {ex.Message}");
}
public class CustomException : Exception
{
public CustomException(string message) : base(message)
{
}
}
try
{
throw new CustomException("Bu özel bir hata.");
}
catch (CustomException ex)
{
Console.WriteLine($"Özel Hata: {ex.Message}");
}
Message
, StackTrace
, InnerException
, Source
, HelpLink
vb.try
{
// Hata olasılığı bulunan kod bloğu
}
catch (Exception ex)
{
// Hata oluştuğunda çalışacak kod bloğu
Console.WriteLine($"Hata Mesajı: {ex.Message}");
Console.WriteLine($"StackTrace: {ex.StackTrace}");
Console.WriteLine($"InnerException: {ex.InnerException}");
Console.WriteLine($"Source: {ex.Source}");
Console.WriteLine($"HelpLink: {ex.HelpLink}");
}
try
{
// Hata olasılığı bulunan kod bloğu
}
catch (Exception ex)
{
// Hata oluştuğunda çalışacak kod bloğu
LogError(ex);
}
try
{
try
{
throw new InvalidOperationException("Inner Exception");
}
catch (Exception innerEx)
{
throw new CustomException("Outer Exception", innerEx);
}
}
catch (CustomException ex)
{
Console.WriteLine($"Outer Exception: {ex.Message}");
Console.WriteLine($"Inner Exception: {ex.InnerException.Message}");
}
static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += GlobalExceptionHandler;
// Uygulama kodları
}
static void GlobalExceptionHandler(object sender, UnhandledExceptionEventArgs e)
{
Exception ex = (Exception)e.ExceptionObject;
Console.WriteLine($"Global Exception Handler: {ex.Message}");
}
Exception Handling (Hata Yönetimi), bir uygulamanın beklenmeyen durumlarla nasıl başa çıkması gerektiğini kontrol etme yeteneğini sağlar. Doğru bir hata yönetimi stratejisi, uygulamanızın daha güvenilir, bakımı kolay ve hata durumlarında daha hızlı tepki verebilmesini sağlar. Bu nedenle, hata yönetimini doğru bir şekilde anlamak ve uygulamak önemlidir.
Asenkron programlama, bir uygulamanın tek bir iş parçacığı üzerinde çalışırken, uzun süreli işlemleri veya giri/çıkış (I/O) operasyonlarını yönetmek için kullanılan bir programlama yaklaşımıdır. Bu, işlemlerin tamamlanmasını beklerken diğer işlemlerin devam etmesine izin verir.
private async Task<int> ExampleAsyncMethod()
{
// Asekron işlemler burada gerçekleştirilir
return 42;
}
private async void CallAsyncMethod()
{
int result = await ExampleAsyncMethod();
Console.WriteLine(result);
}
Task
: Asenkron bir işlemi temsil eden bir türdür.Task<T>
: Asenkron bir işlemi temsil eden ve bir değer döndüren bir türdür.Task.Run
metodu, bir iş parçacığında asenkron bir görevi başlatmak için kullanılır.private async Task<int> ExampleAsyncMethod()
{
return await Task.Run(() =>
{
// İşlemler burada gerçekleştirilir
return 42;
});
}
ConfigureAwait
metodu, bir asenkron metodu belirli bir SynchronizationContext
üzerinde devam ettirmek veya devam ettirmemek için kullanılır.private async Task<int> ExampleAsyncMethod()
{
return await SomeAsyncOperation().ConfigureAwait(false);
}
Parallel.ForEach
ve asenkron işlemleri birleştirirken dikkatli olunmalıdır, çünkü asenkron işlemler genellikle farklı bir iş parçacığında çalışır ve UI iş parçacığına erişimde sorunlara neden olabilir.Parallel.ForEach(items, async item =>
{
await ProcessItemAsync(item);
});
TaskCompletionSource
, bir Task
nesnesini manuel olarak tamamlamak veya başarısızlığa uğratmak için kullanılır. Özellikle asenkron olmayan kodları asenkron bir metot içinde kullanırken faydalı olabilir.private Task<int> ExampleAsyncMethod()
{
TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
// İşlemler burada gerçekleştirilir
tcs.SetResult(42);
return tcs.Task;
}
CancellationTokenSource
, bir işlemi iptal etmek için kullanılır. Asenkron işlemler sırasında kullanıcı tarafından iptal edilebilir.private async Task<int> ExampleAsyncMethod(CancellationToken cancellationToken)
{
await Task.Delay(5000, cancellationToken); // İptal edilebilir gecikme
return 42;
}
private async Task<int> MixedExampleAsyncMethod()
{
int result = SynchronousLibrary.Compute();
return await Task.FromResult(result);
}
Task.WaitAll
metodu, bir dizi görevin tamamlanmasını bekler.Task[] tasks = { Task1(), Task2(), Task3() };
Task.WaitAll(tasks);
Task.WhenAll
metodu, bir dizi görevin tamamlanmasını bekler ve tamamlandığında bir sonuç döndürür.
var results = await Task.WhenAll(Task1(), Task2(), Task3());
Main
metodu da async olarak işaretlenebilir.class Program
{
static async Task Main(string[] args)
{
await DoAsyncWork();
}
static async Task DoAsyncWork()
{
// Asenkron işlemler burada gerçekleştirilir
}
}
try-catch
blokları ile hatalar yönetilmelidir.private async Task<int> ExampleAsyncMethod()
{
try
{
// Asenkron işlemler burada gerçekleştirilir
return 42;
}
catch (Exception ex)
{
Console.WriteLine($"Hata: {ex.Message}");
return -1;
}
}
Async ve Await anahtar kelimeleri, C# dilinde asenkron programlamanın temelini oluşturur. Bu özellikler, uzun süreli işlemleri ve I/O yoğun operasyonları daha etkili bir şekilde yönetmemize olanak tanır. Ancak, doğru kullanılmadığında karmaşıklığa ve hata ayıklama zorluklarına neden olabilir. Doğru senaryolarda ve dikkatlice kullanıldığında, asenkron programlama performansı artırabilir ve daha iyi bir kullanıcı deneyimi sağlayabilir.
Bir sonraki yazıda görüşmek dileğiyle!”