C# kayıt türleri

Tavsiye

Yazılım geliştirme konusunda yeni misiniz? İlk olarak Başlangıç öğreticileri ile başlayın. Yerleşik eşitliğe sahip kısa veri türlerine ihtiyacınız olduğunda kayıtlarla karşılaşırsınız.

Başka bir dilde mi deneyimlisiniz? C# kayıtları, Kotlin'deki veri sınıflarına veya Scala'daki case sınıflarına benzer. Bunlar, derleyici tarafından üretilen eşitlik, ToString ve kopyalama semantiği ile verileri depolamak için optimize edilmiş türlerdir. C#'ye özgü desenler için record class ve record struct ve with ifadeleri bölümlerine göz atın.

record anahtar kelimesi, class veya struct öğelerine uyguladığınız bir değiştiricidir. Derleyiciye, ToString aracılığıyla değer eşitliği, biçimlendirilmiş with ve yıkıcı olmayan bir mutasyon üretmesini söylemektedir. Temel alınan tür, bir sınıf veya yapı, yine de örneklerin başvuru mu yoksa değer semantiği mi kullandığını belirler. Değiştirici, record bu semantiğin üzerine veri dostu davranış ekler. Bir türün birincil rolü verileri depoladığında kayıtları kullanın ve aynı değerlere sahip iki örnek eşit kabul edilmelidir.

Kayıtların ne zaman kullanılacağı

Aşağıdaki koşulların tümü doğru olduğunda bir kayıt kullanın:

  • Türün birincil rolü verileri depolamaktır.
  • Aynı değerlere sahip iki örnek eşit olmalıdır.
  • Değişmezliği arzuluyorsunuz (özellikle record class tipleri için).
  • Manuel olarak yazmadan okunabilir bir ToString istiyorsunuz.

record class ile record struct arasında seçim yaparken:

  • record class devralmanın gerektiği durumlarda veya türün her atamada kopyalanmasının pahalı olacağı kadar büyük olması durumunda kullanın.
  • record struct Kopyalama semantiği ve yığın ayırmanın yararlı olduğu küçük, bağımsız değerler için kullanın.

varlıkları izlemek için başvuru eşitliğine bağlı olan Entity Framework Core içindeki varlık türlerinin kayıtlarından kaçının. Tür seçeneklerinin daha geniş bir karşılaştırması için bkz. Tür türünü seçme.

Bir kayıt tanımla

Bir sınıfa veya yapıya uygulayabilirsiniz record . En basit form, hem oluşturucuyu hem de özellikleri tek bir satırda tanımlayan konumsal parametreleri kullanır:

public record Person(string FirstName, string LastName);

Aynı konumsal söz dizimi record struct türleri için de çalışır.

public record struct Coordinate(double Latitude, double Longitude);

public readonly record struct Temperature(double Celsius)
{
    public double Fahrenheit => Celsius * 9.0 / 5.0 + 32.0;
}

Tek başına record yazmak, record class başvuru türünün bir kısaltmasıdır. Yazma record struct bir değer türü oluşturur. Derleyici her iki durumda da konumsal parametrelerden özellikler oluşturur, ancak varsayılanlar farklıdır:

  • record class: Özellikler init-sadece (oluşturulduktan sonra değiştirilemez).
  • record struct: Özellikler varsayılan olarak okuma ve yazmaya açıktır. Yalnızca readonly yapmak için readonly record struct (init) ekleyin.

Daha fazla denetime ihtiyacınız olduğunda standart özellik söz dizimiyle kayıt da yazabilirsiniz. Örneğin, bir özelliği yalnızca init kullanımı yerine okuma/yazma hale getirmek için:

public record Product
{
    public required string Name { get; init; }
    public decimal Price { get; set; }
}

record class ile record struct karşılaştırması

record Değiştirici, temel alınan türün semantiğini koruduğundan, referansları atadığınızda veya karşılaştırdığınızda bir record class ve bir record struct farklı davranır. Atama işlemi referansı kopyalar. Her iki değişken de aynı nesneye işaret eder. Bir record struct değişkenin atanması verileri kopyalar, bu nedenle bir değişkende yapılan değişiklikler diğerini etkilemez:

// Record class — assignment copies the reference
var p1 = new Person("Grace", "Hopper");
var p2 = p1; // p1 and p2 point to the same object:
Console.WriteLine(ReferenceEquals(p1, p2)); // True

// Record struct — assignment copies the data
var c1 = new Coordinate(47.6062, -122.3321);
var c2 = c1;
c2.Longitude = 0.0; // mutating c2 doesn't affect c1
Console.WriteLine(c1.Longitude); // -122.3321
Console.WriteLine(c2.Longitude); // 0

Kayıt yapıları ayrıca derleyici tarafından oluşturulan değer eşitliği sağlar:

var home = new Coordinate(47.6062, -122.3321);
var copy = home;

Console.WriteLine(home);           // Coordinate { Latitude = 47.6062, Longitude = -122.3321 }
Console.WriteLine(home == copy);   // True — value equality

record class devralmanın gerekeceği durumlarda veya örneklerin kopyalanmasının pahalı olacağı kadar büyük olduğunda seçin. Değer türü kopyalama semantiğinin uygun olduğu küçük, bağımsız veriler için seçin record struct . Değer türü semantiği hakkında daha fazla bilgi için bkz . Yapılar.

Değer eşitliği

Değiştirici hem record sınıflar hem de yapılar derleyici tarafından oluşturulan, özellik başına özellik eşitliği verir. Dört tür türünde de eşitlik şu şekilde çalışır:

  • Düz sınıf: Varsayılan olarak başvuru eşitliğini kullanır. işleci, == verilerin eşleşip eşleşmediğini değil, iki değişkenin aynı nesneye işaret edip etmediğini denetler.
  • Düz yapı: ValueType.Equals kullanılarak değer eşitliğini destekler, ancak varsayılan uygulama, daha yavaş olan ve ==/!= işleçlerini oluşturmayan yansıma kullanır.
  • record class: Derleyici, her özellik değerini karşılaştıran yöntemler ve EqualsGetHashCode== işleçler oluşturur./!= Aynı verilere sahip iki ayrı nesne eşittir.
  • record struct: Derleyici tarafından oluşturulan eşitlik ile aynı record class, ancak yansıma kullanılmadan, bu da düz yapı eşitliğinden daha hızlı olmasını sağlar.

Aşağıdaki örnekte kayıt sınıfı eşitliği gösterilmektedir:

// Person is a record type with three properties: FirstName, LastName, and PhoneNumbers.
var phones = new string[] { "555-1234" };
var person1 = new Person("Grace", "Hopper", phones);
var person2 = new Person("Grace", "Hopper", phones);

Console.WriteLine(person1 == person2);              // True
Console.WriteLine(ReferenceEquals(person1, person2)); // False

person1.PhoneNumbers[0] = "555-9999";
Console.WriteLine(person2.PhoneNumbers[0]); // 555-9999 — same array

İki Person örnek farklı nesnelerdir, ancak tüm özellik değerleri eşleştiğinden eşittir. Dizi özellikleri, içindekilere göre değil başvuruya göre karşılaştırır. Dizinin kendisi kopyalanmadığı için, paylaşılan dizideki değişiklikler her iki kayıttan da görülebilir.

with ifadeleriyle tahribatsız mutasyon

Kayıtlar genellikle sabittir, bu nedenle oluşturma işleminden sonra bir özelliği değiştiremezsiniz. İfade with , bir veya daha fazla özelliği değiştirilmiş bir kopya oluşturur ve özgün kaydı değişmeden bırakır. Bu yaklaşım hem record class hem de record struct türleri için çalışır.

var original = new Person("Grace", "Hopper");
var modified = original with { FirstName = "Margaret" };

Console.WriteLine(original); // Person { FirstName = Grace, LastName = Hopper }
Console.WriteLine(modified); // Person { FirstName = Margaret, LastName = Hopper }
Console.WriteLine(original == modified); // False

var copy = original with { };
Console.WriteLine(original == copy); // True

Aynı söz dizimi, record struct türleri için de çalışır.

var shifted = home with { Longitude = -122.0 };
Console.WriteLine(shifted);        // Coordinate { Latitude = 47.6062, Longitude = -122 }
Console.WriteLine(home == shifted); // False

İfade with mevcut örneği kopyalar ve belirtilen özellik değişikliklerini uygular.

Konumsal kayıtlar ve yapısızlaştırma

Konumsal kayıtlar, özellik değerlerini tek tek değişkenlere ayıklamak için kullandığınız bir Deconstruct yöntem oluşturur:

var (first, last) = person;
Console.WriteLine($"{first} {last}");
// Grace Hopper

Yapısızlaştırma hem record class hem de record struct türleriyle çalışır. Bunu atamalarda, foreach döngülerde ve desen eşleştirmede kullanabilirsiniz.

Kayıt devralma

, record class başka bir record classöğesinden devralabilir. Bir kayıt normal sınıftan devralamaz ve bir sınıf bir kayıttan devralamaz:

public record Student(string FirstName, string LastName, int GradeLevel)
    : Person(FirstName, LastName);

Değer eşitliği denetimleri çalışma zamanı türünü içerir, bu nedenle aynı Person ve Student'ye sahip FirstName ve LastName, eşit olarak kabul edilmez. Kayıt yapıları devralmayı desteklemez çünkü yapılar diğer türlerden devralamaz.

Ayrıca bakınız