Değer Eşitliği ve Yapıdan Çıkarma
Record yapısal eşitliğini anlayın, Equals/GetHashCode'u geçersiz kılın ve yapıdan çıkarma desenlerini kullanın.
Değer Eşitliği ve Yapıdan Çıkarma, CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C# Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C# Academy kursu toplamda 4 dersten oluşur.
Kayıt Eşitliğine Derinlemesine Bakış
Kayıtlar, tüm özellikleri yapısal olarak karşılaştıran Equals, GetHashCode ve ==/!= işleçlerini otomatik olarak oluşturur. Bunun nasıl çalıştığını anlamak, kayıtları doğru kullanmanıza ve gerektiğinde geçersiz kılmanıza yardımcı olur.
Otomatik Oluşturulan Eşitlik Nasıl Çalışır?
Derleyici, her özelliği EqualityComparer<T>.Default kullanarak karşılaştıran kodu oluşturur. Başvuru türü özelliklerde bu, başvuru eşitliği değil, ilgili türün kendi Equals yöntemidir.
public record Address(string Street, string City);
public record Person(string Name, Address HomeAddress);
var a = new Person("Alice", new Address("123 Main", "NYC"));
var b = new Person("Alice", new Address("123 Main", "NYC"));
Console.WriteLine(a == b); // True — deep structural equality
// Equality checks:
// Name: "Alice" == "Alice" ✓
// HomeAddress: compares Address properties recursively ✓Oluşturulan Eşitliği Geçersiz Kılma
Özel bir eşitlik mantığı istediğinizde bir kayıttaki Equals ve GetHashCode yöntemlerini geçersiz kılabilirsiniz; örneğin yalnızca özelliklerin bir alt kümesini karşılaştırabilirsiniz.
public record Customer(int Id, string Name, string Email)
{
// Consider customers equal if they have the same ID,
// regardless of name or email changes
public virtual bool Equals(Customer? other)
=> other is not null && Id == other.Id;
public override int GetHashCode() => Id.GetHashCode();
}Koleksiyonlarda Kayıtlar
Kayıtlar yapısal eşitliğe sahip IEquatable<T> uyguladığı için sözlük anahtarları olarak, HashSets içinde ve LINQ'in Distinct ile GroupBy yöntemleriyle doğru çalışır.
public record Tag(string Name, string Color);
var tags = new List<Tag>
{
new("C#", "blue"), new("C#", "blue"), new("dotnet", "purple")
};
var unique = tags.Distinct().ToList(); // [Tag(C#, blue), Tag(dotnet, purple)]
var set = new HashSet<Tag>(tags);
set.Contains(new Tag("C#", "blue")); // trueParçalarına Ayırma: Temel Bilgiler
Konumsal kayıtlar, her konumsal özellik için out parametrelerine sahip bir Deconstruct yöntemini otomatik olarak oluşturur. Bu, demet benzeri açmayı mümkün kılar.
public record Point(double X, double Y);
public record RGB(byte R, byte G, byte B);
var p = new Point(3.0, 4.0);
var (x, y) = p; // deconstruct
Console.WriteLine($"{x}, {y}");
var color = new RGB(255, 128, 0);
var (r, g, b) = color;
Console.WriteLine($"R={r}, G={g}, B={b}");Desen Eşleştirmede Parçalarına Ayırma
switch ifadelerinde parçalarına ayrılan kayıtlar, güçlü konumsal desen eşleştirmeyi mümkün kılar.
public record Point(int X, int Y);
string Classify(Point p) => p switch
{
(0, 0) => "Origin",
(int x, 0) => $"X-axis at {x}",
(0, int y) => $"Y-axis at {y}",
(int x, int y) when x == y => $"Diagonal at {x}",
(int x, int y) => $"Point ({x}, {y})"
};
Console.WriteLine(Classify(new Point(0, 0))); // Origin
Console.WriteLine(Classify(new Point(3, 3))); // Diagonal at 3Özel Deconstruct Yöntemleri
Konumsal olmayan kayıtlar (ve tüm sınıflar), elle bir Deconstruct yöntemi ekleyebilir. Genişletme yöntemleri de mevcut türlerde parçalarına ayırmayı mümkün kılabilir.
public class Temperature
{
public double Celsius { get; }
public Temperature(double c) => Celsius = c;
// Manual Deconstruct
public void Deconstruct(out double celsius, out double fahrenheit)
{
celsius = Celsius;
fahrenheit = Celsius * 9 / 5 + 32;
}
}
var t = new Temperature(100);
var (c, f) = t;
Console.WriteLine($"{c}°C = {f}°F"); // 100°C = 212°FParçalarına Ayırmanın Bölümlerini Yok Sayma
Parçalarına ayırmanın istenmeyen bölümlerini yok saymak için (demetlerdeki yok saymalar gibi) atılabilir değerleri (_) kullanın.
public record Order(int Id, string Customer, decimal Total, DateTime Date);
var order = new Order(42, "Alice", 99.99m, DateTime.UtcNow);
// Only want Id and Total
var (id, _, total, _) = order;
Console.WriteLine($"Order {id}: ${total}");
// In switch: ignore some fields
string Classify(Order o) => o switch
{
(_, _, > 1000, _) => "High value",
(_, _, > 100, _) => "Medium value",
_ => "Low value"
};Özellik Desenleri ve Konumsal Desenler
Kayıtlar hem konumsal desenleri (konuma göre) hem de özellik desenlerini (ada göre) destekler. Çok sayıda özelliğe sahip kayıtlarda özellik desenleri daha okunabilirdir.
public record Order(int Id, string Status, decimal Total);
// Positional pattern:
string DescribePos(Order o) => o switch
{
(_, "Shipped", > 100) => "High-value shipped",
_ => "Other"
};
// Property pattern (more readable):
string DescribeProp(Order o) => o switch
{
{ Status: "Shipped", Total: > 100 } => "High-value shipped",
{ Status: "Cancelled" } => "Cancelled",
_ => "Other"
};Gerçek Dünya: Result Türü Deseni
Kayıtları ve parçalarına ayırmayı kullanan, ayırt edilebilir birleşim tarzı bir Result türü; hataları ele almaya yönelik işlevsel bir yaklaşım.
public abstract record Result<T>;
public record Success<T>(T Value) : Result<T>;
public record Failure<T>(string Error) : Result<T>;
Result<Order> PlaceOrder(CreateOrderRequest req)
{
if (req.Quantity <= 0)
return new Failure<Order>("Quantity must be positive");
var order = CreateOrder(req);
return new Success<Order>(order);
}
// Consuming:
var result = PlaceOrder(request);
switch (result)
{
case Success<Order>(var order):
return Results.Created($"/orders/{order.Id}", order);
case Failure<Order>(var error):
return Results.BadRequest(error);
}Hızlı Denetim
Parçalarına ayırma ifadesinde atılabilir değer (_) kullanmak ne yapar?
Değer Eşitliği ve Parçalarına Ayırma Özeti
Önemli çıkarımlar:
- Otomatik oluşturulan eşitlik, tüm özellikleri yapısal ve yinelemeli olarak karşılaştırır
- Kendinize özgü kimlik mantığı için kayıt türlerinde Equals/GetHashCode'u geçersiz kılın
- Kayıt türleri, HashSet öğeleri ve sözlük anahtarları olarak doğru şekilde çalışır
- Konumsal kayıt türleri Deconstruct'i otomatik olarak oluşturur — var (a, b) = record kullanın
- Atama yapılmayan değerler (_) ayrıştırmada istenmeyen konumsal değerleri yok sayar
- Özellik kalıpları ({Status: "X"}), karmaşık kayıt türlerinde konumsal kalıplara göre daha okunabilirdir
Sıkça Sorulan Sorular
“Değer Eşitliği ve Yapıdan Çıkarma” dersi ücretsiz mi?
Evet — “Değer Eşitliği ve Yapıdan Çıkarma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C# Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C# Academy kursu toplamda 4 dersten oluşur.
“Değer Eşitliği ve Yapıdan Çıkarma” dersinde ne öğreneceğim?
Record yapısal eşitliğini anlayın, Equals/GetHashCode'u geçersiz kılın ve yapıdan çıkarma desenlerini kullanın. C# Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
C# Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te C# Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.
“Değer Eşitliği ve Yapıdan Çıkarma” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu C# Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her C# Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Record Türleri: Temeller ve Sözdizimi
- init ve with ile Değişmezlik
- Değer Eşitliği ve Yapıdan Çıkarma
- Alan Odaklı Tasarımda Record'lar