C# için hap gibi kısa kısa bilgiler Part-2 (50 Bilgi)
Class ve Struct Farklılıkları: Class ve Struct, veri yapılarını temsil eder; ancak class, referans tipidir ve heap bellekte saklanır, struct ise değer tipidir ve stack bellekte tutulur. Struct genellikle hafif ve sık erişilen veri yapıları için kullanılır. Örneğin, bir Point yapısı iki int koordinat içerebilir. Class, karmaşık nesneler ve veri işleme mantıkları için daha uygundur.
class Person { public string Name; } struct Point { public int X, Y; }
Properties (Özellikler): C#’da get ve set anahtar kelimeleri ile tanımlanan özellikler, bir nesnenin durumunu gizli tutarak kapsüllemeyi sağlar. Örneğin, bir Person sınıfında Name özelliği tanımlayarak hem okunabilir hem de yazılabilir yapabilirsiniz. Özelliklere ayrıca private veya protected kısıtlamalar ekleyebilirsiniz.
public class Person { private string _name; public string Name { get { return _name; } set { _name = value; } } }
Auto-Implemented Properties: Otomatik özellikler, private bir alan belirtmeden özellik tanımlamanıza izin verir. Sınıfın değişkeni C# tarafından otomatik olarak yönetilir. Sadece özellik adı ve türünü yazarak değerlerin kontrolünü sağlayabilirsiniz.
public class Book { public string Title { get; set; } public string Author { get; set; } }
Read-Only Properties: Bir özelliğin yalnızca okunabilir olması gerekiyorsa, get ifadesini tanımlayıp set ifadesini kaldırarak sadece okuma işlemlerine izin verebilirsiniz. Ayrıca, readonly anahtar kelimesi de benzer bir amaçla alan tanımlamalarında kullanılır.
public class Circle { private readonly double _radius; public double Radius { get { return _radius; } } public Circle(double radius) { _radius = radius; } }
Constructors (Yapıcı Metotlar): Constructor, bir sınıftan yeni nesne oluşturulduğunda çağrılan özel bir metottur. Parametre alarak nesnenin ilk değerlerini atayabilir. Örneğin, bir Car sınıfı oluştururken Make ve Model değerlerini almak için bir yapıcı metot kullanabilirsiniz.
public class Car { public string Make { get; } public string Model { get; } public Car(string make, string model) { Make = make; Model = model; } }
Static Constructor: Static yapıcılar, yalnızca bir kez çağrılır ve sınıf ilk kez erişildiğinde tetiklenir. Statik alanları veya sınıf düzeyindeki ayarları başlatmak için kullanılır. Statik yapıcılar herhangi bir erişim belirleyici içermez ve parametre almaz.
public class Settings { public static int MaxLimit; static Settings() { MaxLimit = 100; } }
Partial Classes (Kısmi Sınıflar): Bir sınıfı birden fazla dosyada bölmek için partial anahtar kelimesini kullanabilirsiniz. Kapsamlı sınıfları bölmek, farklı dosyalarda iş bölümü yapmayı sağlar. Örneğin, bir Employee sınıfı hem iş bilgilerini hem de kişisel bilgileri içerebilir ve bu iki ayrı dosyada düzenlenebilir.
// Employee_Personal.cs public partial class Employee { public string Name; } // Employee_Job.cs public partial class Employee { public string Position; }
Inheritance (Miras Alma): Inheritance (kalıtım), bir sınıfın başka bir sınıftan türeyerek özelliklerini devralmasını sağlar. Örneğin, Person sınıfından türeyen Student sınıfı, Person sınıfının tüm özelliklerini ve davranışlarını miras alır. : Person ile kalıtımı belirtebiliriz.
public class Person { public string Name; } public class Student : Person { public string School; }
Sealed Classes: Bir sınıf sealed anahtar kelimesiyle tanımlandığında başka bir sınıf tarafından miras alınamaz. Bu durum, sınıfın değiştirilmesini istemediğiniz senaryolar için idealdir. Math gibi genel işlevleri içeren sınıflar genellikle sealed olarak tanımlanır.
public sealed class MathHelper { public static int Add(int x, int y) { return x + y; } }
Abstract Classes (Soyut Sınıflar): Abstract sınıflar, yalnızca miras alınmak üzere tasarlanmış sınıflardır ve soyut metotlar içerir. Bu soyut metotlar yalnızca imza içerir ve türetilen sınıflarda uygulanması zorunludur. Bir Shape sınıfı Area gibi bir metodu soyut olarak tanımlayabilir.
public abstract class Shape { public abstract double Area(); } public class Circle : Shape { private double _radius; public Circle(double radius) { _radius = radius; } public override double Area() { return Math.PI * _radius * _radius; } }
Interfaces (Arayüzler): Interface, bir sınıfın uygulaması gereken metot ve özelliklerin tanımlandığı bir şablondur. Arayüzler I harfiyle başlar ve sınıflar birden fazla arayüzü implemente edebilir. Bu durum, farklı türlerin ortak davranışlarını tanımlamak için kullanılır. Örneğin, IMovable arayüzü hareket etme yeteneğini tanımlar.
public interface IMovable { void Move(); } public class Car : IMovable { public void Move() { Console.WriteLine("Car is moving"); } }
Explicit Interface Implementation: Bir sınıf aynı isimde iki arayüz metodu içeriyorsa, interface adı kullanılarak açık bir şekilde uygulanabilir. Bu, arayüz metotlarını ayrı ayrı çağırmanıza olanak tanır.
public interface IFlyable { void Move(); } public interface IMovable { void Move(); } public class Bird : IFlyable, IMovable { void IFlyable.Move() { Console.WriteLine("Flying"); } void IMovable.Move() { Console.WriteLine("Moving"); } }
Polymorphism (Çok Biçimlilik): Polimorfizm, bir nesnenin, bir arayüz veya temel sınıf türünde çağrıldığında farklı davranışlar sergilemesine olanak tanır. Örneğin, bir Animal türü olan Dog sınıfı, Speak metodu farklı davranış gösterir.
public class Animal { public virtual void Speak() { Console.WriteLine("Animal speaks"); } } public class Dog : Animal { public override void Speak() { Console.WriteLine("Bark"); } }
Virtual ve Override: Bir virtual metot, türetilen sınıfta override ile yeniden tanımlanabilir. Bu yapı, kalıtılan bir metodu değiştirme imkanı tanır ve polimorfizmin uygulanmasını sağlar.
public class Employee { public virtual void Work() { Console.WriteLine("Working"); } } public class Developer : Employee { public override void Work() { Console.WriteLine("Coding"); } }
List Koleksiyonları: List, generic bir koleksiyondur ve dinamik olarak büyüyüp küçülebilir. Listeye eleman eklemek için Add, çıkarmak için Remove, tüm elemanları listelemek için foreach gibi yöntemler kullanılır. Listenin boyutu, eleman ekledikçe veya çıkardıkça otomatik olarak ayarlanır.
List<int> numbers = new List<int> { 1, 2, 3 }; numbers.Add(4); numbers.Remove(1);
Dictionary<TKey, TValue>: Dictionary<TKey, TValue>, anahtar-değer çifti depolayan bir koleksiyondur. Her bir anahtar benzersizdir ve anahtar üzerinden hızlı erişim sağlar. Örneğin, bir Dictionary<int, string> öğrenci numaraları ve isimleri eşleştirmek için kullanılabilir.
Dictionary<int, string> students = new Dictionary<int, string>(); students.Add(101, "Ali"); students[102] = "Ayşe";
HashSet Koleksiyonu: HashSet, benzersiz elemanları depolamak için idealdir. Elemanlar sırasızdır ve aynı eleman birden fazla kez eklenemez. Benzersiz öğeleri saklamak veya bir veri kümesinde yinelenenleri önlemek için kullanılır.
HashSet<string> colors = new HashSet<string> { "Red", "Green" }; colors.Add("Blue"); colors.Add("Red"); // Eklenmez, çünkü zaten mevcut.
Queue (Kuyruklar): Queue, birinci giren birinci çıkar (FIFO) prensibine göre çalışan bir veri yapısıdır. Kuyruğa eleman eklemek için Enqueue, çıkarmak için Dequeue kullanılır. Bu veri yapısı sırayla işlem yapmayı gerektiren senaryolar için uygundur.
Queue<string> tasks = new Queue<string>(); tasks.Enqueue("Task 1"); tasks.Enqueue("Task 2"); string nextTask = tasks.Dequeue();
Stack (Yığınlar): Stack, son giren ilk çıkar (LIFO) prensibiyle çalışan bir veri yapısıdır. Push ile ekleme ve Pop ile çıkarma işlemleri yapılır. Özellikle işlem geçmişini veya geri alma işlemlerini saklamak için idealdir.
Stack<int> numbers = new Stack<int>(); numbers.Push(1); numbers.Push(2); int lastNumber = numbers.Pop(); // Çıkarılan son eleman: 2
LinkedList: LinkedList, her bir düğümün bir sonraki ve/veya önceki düğüme işaret ettiği veri yapısıdır. Bu yapıyı kullanarak hızlı bir şekilde ekleme ve silme işlemleri yapılabilir. AddFirst ve AddLast gibi metotlarla listenin başına veya sonuna eleman eklenebilir.
LinkedList<string> days = new LinkedList<string>(); days.AddLast("Monday"); days.AddFirst("Sunday");
SortedList<TKey, TValue>: SortedList<TKey, TValue>, anahtar-değer çiftlerini sıralı bir şekilde saklar. Anahtarları otomatik olarak sıralar ve SortedList’in her zaman sıralı bir koleksiyon olduğunu garanti eder. Bu, küçük boyutlu sıralı veriler için idealdir.
SortedList<int, string> students = new SortedList<int, string>(); students.Add(2, "Ali"); students.Add(1, "Ayşe");
ObservableCollection: ObservableCollection, koleksiyonda yapılan değişiklikleri bildirimlerle gözlemlemenizi sağlar. INotifyCollectionChanged arayüzünü uygular ve veri bağlama senaryolarında kullanışlıdır. Örneğin, bir ListBox veya DataGrid’e veri bağladığınızda, koleksiyon değişikliklerini otomatik olarak yansıtabilirsiniz.
ObservableCollection<string> items = new ObservableCollection<string>(); items.CollectionChanged += (s, e) => Console.WriteLine("Collection changed"); items.Add("Item 1");
Tuple<T1, T2, …> Yapıları: Tuple, birden fazla değeri tek bir yapıda saklamak için kullanılır. Tuple’lar ile hızlıca birkaç değeri tek bir yapı olarak döndürebilir veya saklayabilirsiniz. Örneğin, bir metodun hem başarı durumunu hem de mesajını döndürmek için kullanabilirsiniz.
var result = Tuple.Create(true, "Success"); bool isSuccess = result.Item1; string message = result.Item2;
Concurrent Collections (Eşzamanlı Koleksiyonlar): ConcurrentDictionary, ConcurrentQueue, ConcurrentBag gibi koleksiyonlar, çoklu iş parçacığı senaryolarında güvenle kullanılabilir. Bu koleksiyonlar, çok iş parçacıklı ortamlarda veri yarışını önler. ConcurrentDictionary, aynı anda birden fazla iş parçacığı tarafından güvenle erişilen bir sözlüktür.
ConcurrentDictionary<int, string> data = new ConcurrentDictionary<int, string>(); data.TryAdd(1, "Value1");
Delegates (Delegeler): Delegate, bir metot referansını tutar ve metodun çalışma zamanında çağrılmasını sağlar. Delegeler, olay tabanlı programlamada sıkça kullanılır ve Action, Func gibi hazır delegeler sayesinde kodun okunabilirliği artırılır.
public delegate void MessageDelegate(string message); public class Messenger { public void SendMessage(MessageDelegate msgDel, string message) { msgDel(message); } }
Events (Olaylar): Event, bir nesnede meydana gelen bir durumu temsil eder ve bir delege kullanılarak tetiklenir. Olayları, nesnelerin arasında bildirim göndermek için kullanabilirsiniz. Örneğin, bir Button sınıfı tıklandığında bir olay tetikleyebilir.
public class Button { public event EventHandler Click; public void OnClick() { Click?.Invoke(this, EventArgs.Empty); } }
Action ve Func Delegeleri: Action ve Func, C#’da yaygın olarak kullanılan delegelerdir. Action, dönüş değeri olmayan bir metodu işaret ederken Func dönüş değeri olan metodları temsil eder. Bu hazır delegeler, lambda ifadeleriyle birlikte sıkça kullanılır.
Action<string> print = Console.WriteLine; Func<int, int, int> add = (a, b) => a + b;
Lambda İfadeleri: Lambda ifadeleri, C#’da kısa ve öz metotlar tanımlamak için kullanılır. => operatörü kullanılarak yazılır ve LINQ ile yaygın bir şekilde kullanılır. Örneğin, bir liste içerisindeki sayıların çift olup olmadığını kontrol etmek için lambda kullanabilirsiniz.
List<int> numbers = new List<int> { 1, 2, 3, 4 }; var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
Expression Trees: Expression Tree, bir lambda ifadesini temsil eden veri yapılarıdır ve dinamik olarak analiz edilip işlenebilir. Bu yapı, özellikle LINQ sorgularında veri analizinde kullanılır.
Expression<Func<int, bool>> expr = num => num > 5; Console.WriteLine(expr.Body); // Çıktı: (num > 5)
Anonymous Methods (Anonim Metotlar): Anonim metotlar, bir delegeye direkt olarak atanabilen metotlardır ve dönüş değeri gerektirmez. Küçük kod bloklarını hızlıca tanımlamak için kullanılır.
Action<string> greet = delegate (string name) { Console.WriteLine($"Hello, {name}!"); }; greet("Eren");
Predicate Delegeleri: Predicate, bir öğeyi bool döndüren bir şarta göre değerlendiren bir delege türüdür. List gibi koleksiyonlarda Find veya FindAll gibi metodlarla sıklıkla kullanılır.
Predicate<int> isEven = x => x % 2 == 0; List<int> numbers = new List<int> { 1, 2, 3, 4 }; var evenNumber = numbers.Find(isEven); // Çıktı: 2
Multicast Delegeler: Birden fazla metodu tutan delegelerdir ve aynı delege çağrıldığında sırayla bu metotları çalıştırır. Örneğin, bir hata durumunda hem bir dosyaya yazmak hem de kullanıcıya bildirmek isterseniz Multicast Delegate kullanabilirsiniz.
Action logActions = () => Console.WriteLine("Log to Console"); logActions += () => File.WriteAllText("log.txt", "Log to File"); logActions();
EventHandler Delegate: C#’ın varsayılan EventHandler delegesi, olaylar için bir standart sağlar. Olaylar ile birlikte sender ve EventArgs parametrelerini içerir.
public event EventHandler<EventArgs> DataProcessed;
EventHandler: EventHandler sınıfının generic versiyonudur. Bu tür, olay işleme metoduna EventArgs yerine belirli bir EventArgs türü göndermenizi sağlar. Örneğin, özel bir olay için CustomEventArgs kullanabilirsiniz.
public event EventHandler<CustomEventArgs> CustomEvent; public class CustomEventArgs : EventArgs { public string Message { get; set; } }
LINQ (Language-Integrated Query): LINQ, C#’da veri kaynakları üzerinde sorgulama yapmanıza olanak tanır. SQL benzeri bir sözdizimine sahiptir ve koleksiyonlar, diziler, XML gibi farklı veri kaynakları üzerinde çalışabilir. LINQ, veri manipülasyonunu daha okunabilir ve hatasız hale getirir.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; var evenNumbers = from num in numbers where num % 2 == 0 select num;
LINQ Method Syntax: LINQ method syntax, Where, Select, OrderBy gibi metodlarla sorgulama yapmanızı sağlar. Bu, özellikle lambda ifadeleri ile birleştirildiğinde güçlü hale gelir ve daha kısa, okunabilir kod yazmanıza olanak tanır.
List<string> names = new List<string> { "Ali", "Ayşe", "Ahmet" }; var aNames = names.Where(name => name.StartsWith("A")).ToList();
Deferred Execution (Gecikmeli Çalışma): LINQ sorguları varsayılan olarak “deferred execution” ile çalışır, yani sorgu tanımlandığında değil, veri çekildiğinde çalışır. Bu özellik, performans optimizasyonu sağlar ve veriyi sorgulamadan önce değiştirme imkanı tanır.
var query = numbers.Where(n => n > 2); // Sorgu burada tanımlandı ama henüz çalışmadı. numbers.Add(3); var result = query.ToList(); // Sorgu burada çalışır.
Immediate Execution (Anında Çalışma): ToList(), ToArray() veya Count() gibi metodlar, sorgunun hemen çalışmasını sağlar. Bu, özellikle bir sorguyu anında çalıştırmak ve sonucun beklenen şekilde dondurulmasını sağlamak için kullanılır.
var immediateResult = numbers.Where(n => n > 2).ToList(); // Sorgu anında çalışır.
SelectMany Kullanımı: SelectMany, iç içe koleksiyonları düzleştirmek için kullanılır. Özellikle bir sınıfın içerisindeki başka koleksiyonlara erişmek veya çok boyutlu verilerle çalışırken kullanışlıdır. Bir liste içindeki her elemanın alt listelerini tek bir düz listeye dönüştürür.
List<List<int>> numberGroups = new List<List<int>> { new List<int> { 1, 2 }, new List<int> { 3, 4 } }; var flatList = numberGroups.SelectMany(group => group).ToList();
GroupBy Kullanımı: GroupBy, veriyi belirli bir kritere göre gruplamak için kullanılır. Bu özellik, veriyi belirli bir kategoriye göre sıralamak veya raporlamak için yararlıdır. Örneğin, bir müşteri listesini ülkelere göre gruplamak için GroupBy kullanılabilir.
List<string> names = new List<string> { "Ali", "Ayşe", "Ahmet", "Berk" }; var groupedNames = names.GroupBy(name => name[0]); // Harf başına grupla.
Join İle Birleştirme: Join metodu, iki veri kaynağını belirli bir anahtar üzerinden birleştirir. Örneğin, bir sipariş listesi ile müşteri listesi, müşteri ID’si üzerinden birleştirilebilir. SQL’deki “JOIN” işlemi gibi çalışır.
var joined = customers.Join(orders, customer => customer.Id, order => order.CustomerId, (customer, order) => new { customer.Name, order.OrderId });
Aggregate Metodu: Aggregate, bir koleksiyondaki tüm elemanları birleştirip tek bir sonuç döndürür. Bu, toplama, çarpma veya belirli bir şekilde metin birleştirme gibi işlemler için idealdir. Örneğin, bir sayı listesinin toplamını hesaplamak için kullanılabilir.
List<int> numbers = new List<int> { 1, 2, 3, 4 }; int sum = numbers.Aggregate((total, next) => total + next);
All ve Any Metotları: All, bir koleksiyondaki tüm elemanların belirli bir koşulu karşılayıp karşılamadığını kontrol ederken Any, en az bir elemanın koşulu karşılayıp karşılamadığını kontrol eder. Bu metotlar, veri doğrulama ve filtreleme için çok kullanışlıdır.
List<int> numbers = new List<int> { 1, 2, 3, 4 }; bool allEven = numbers.All(n =< n % 2 == 0); // False, çünkü tümü çift değil. bool anyEven = numbers.Any(n => n % 2 == 0); // True, çünkü en az bir çift sayı var.
Distinct Kullanımı: Distinct, bir koleksiyondaki yinelenen elemanları çıkararak benzersiz bir liste oluşturur. Özellikle büyük veri kümelerinde yinelenenleri temizlemek için idealdir.
List<int> numbers = new List<int> { 1, 2, 2, 3, 4, 4 }; var uniqueNumbers = numbers.Distinct().ToList();
Bir yanıt yazın