Aracılığıyla paylaş


Kayıtlar (C# başvurusu)

Verileri kapsüllemek için yerleşik işlevsellik sağlayan bir başvuru türü tanımlamak için değiştiriciyi kullanırsınızrecord. C# 10, söz diziminin record class bir başvuru türünü netleştirmesine ve record struct benzer işlevlere sahip bir değer türü tanımlamasına olanak tanır.

Bir kayıtta birincil oluşturucu bildirdiğinizde, derleyici birincil oluşturucu parametreleri için genel özellikler oluşturur. Bir kaydın birincil oluşturucu parametreleri konumsal parametreler olarak adlandırılır. Derleyici, birincil oluşturucuyu veya konumsal parametreleri yansıtan konumsal özellikler oluşturur. Derleyici, değiştiricisi olmayan türlerde birincil oluşturucu parametrelerinin record özelliklerini sentezlemiyor.

Aşağıdaki iki örnek başvuru türlerini (veya record class) gösterir record :

public record Person(string FirstName, string LastName);
public record Person
{
    public required string FirstName { get; init; }
    public required string LastName { get; init; }
};

Aşağıdaki iki örnek değer türlerini gösterir record struct :

public readonly record struct Point(double X, double Y, double Z);
public record struct Point
{
    public double X { get; init; }
    public double Y { get; init; }
    public double Z { get; init; }
}

Ayrıca, değiştirilebilir özelliklere ve alanlara sahip kayıtlar da oluşturabilirsiniz:

public record Person
{
    public required string FirstName { get; set; }
    public required string LastName { get; set; }
};

Hem konumsal kayıt yapıları hem de konumsal parametre içermeyen kayıt yapıları da değiştirilebilir:

public record struct DataMeasurement(DateTime TakenAt, double Measurement);
public record struct Point
{
    public double X { get; set; }
    public double Y { get; set; }
    public double Z { get; set; }
}

Kayıtlar değişebilir olsa da, bunlar öncelikli olarak sabit veri modellerini desteklemeye yöneliktir. Kayıt türü aşağıdaki özellikleri sunar:

Yukarıdaki örneklerde, başvuru türü olan kayıtlarla değer türü olan kayıtlar arasındaki bazı farklar gösterilmektedir:

  • A record veya a, record class bir başvuru türü bildirir. Anahtar class sözcük isteğe bağlıdır, ancak okuyucular için netlik sağlayabilir. A record struct , bir değer türü bildirir.
  • Konumsal özellikler ve readonly record structiçinde record class sabittir. bir içinde record structdeğiştirilebilirler.

Bu makalenin geri kalanında hem hem de record classrecord struct türleri ele alınmaktadır. Farklılıklar her bölümde ayrıntılı olarak anlatılır. ile arasında karar vermeniz, ile record classrecord struct arasında class karar vermeyle benzer bir structöğesini belirlemeniz gerekir. Kayıt terimi , tüm kayıt türleri için geçerli olan davranışı tanımlamak için kullanılır. ya da record structrecord class sırasıyla yalnızca yapı veya sınıf türleri için geçerli olan davranışı açıklamak için kullanılır. Türü record struct C# 10'da tanıtıldı.

Özellik tanımı için konumsal söz dizimi

Bir kaydın özelliklerini bildirmek ve bir örnek oluştururken özellik değerlerini başlatmak için konumsal parametreleri kullanabilirsiniz:

public record Person(string FirstName, string LastName);

public static void Main()
{
    Person person = new("Nancy", "Davolio");
    Console.WriteLine(person);
    // output: Person { FirstName = Nancy, LastName = Davolio }
}

Özellik tanımı için konumsal söz dizimini kullandığınızda, derleyici şunları oluşturur:

  • Kayıt bildiriminde sağlanan her konumsal parametre için bir genel otomatik otomatikleştirilmiş özellik.
    • Türler ve readonly record struct türler içinrecord: Yalnızca başlatma özelliği.
    • Türler için record struct : Okuma-yazma özelliği.
  • Parametreleri kayıt bildirimindeki konumsal parametrelerle eşleşen bir birincil oluşturucu.
  • Kayıt yapısı türleri için, her alanı varsayılan değerine ayarlayan parametresiz bir oluşturucu.
  • Deconstruct Kayıt bildiriminde sağlanan her konumsal parametre için parametresi olan bir out yöntem. yöntemi, konumsal söz dizimi kullanılarak tanımlanan özellikleri yok eder; standart özellik söz dizimi kullanılarak tanımlanan özellikleri yoksayar.

Derleyicinin kayıt tanımından oluşturduğu bu öğelerden herhangi birine öznitelik eklemek isteyebilirsiniz. Konumsal kaydın özelliklerine uyguladığınız herhangi bir özniteliğe hedef ekleyebilirsiniz. Aşağıdaki örnek, kaydın System.Text.Json.Serialization.JsonPropertyNameAttribute her özelliğine Person öğesini uygular. Hedef, property: özniteliğin derleyici tarafından oluşturulan özelliğe uygulandığını gösterir. Diğer değerler field: , özniteliği alana uygulamak ve param: özniteliğini parametresine uygulamaktır.

/// <summary>
/// Person record type
/// </summary>
/// <param name="FirstName">First Name</param>
/// <param name="LastName">Last Name</param>
/// <remarks>
/// The person type is a positional record containing the
/// properties for the first and last name. Those properties
/// map to the JSON elements "firstName" and "lastName" when
/// serialized or deserialized.
/// </remarks>
public record Person([property: JsonPropertyName("firstName")] string FirstName, 
    [property: JsonPropertyName("lastName")] string LastName);

Yukarıdaki örnekte, kayıt için XML belgeleri açıklamalarının nasıl oluşturulacağı da gösterilmektedir. Birincil oluşturucunun <param> parametrelerine yönelik belgeler eklemek için etiketini ekleyebilirsiniz.

Oluşturulan otomatik tanımlama özelliği tanımı istediğiniz gibi değilse, aynı ada sahip kendi özelliğinizi tanımlayabilirsiniz. Örneğin, erişilebilirliği veya değişebilirliği değiştirmek ya da ya set da get erişimci için bir uygulama sağlamak isteyebilirsiniz. Özelliği kaynağınızda bildirirseniz, kaydın konumsal parametresinden başlatmanız gerekir. Özelliğiniz otomatik olarak önerilen bir özellikse, özelliğini başlatmanız gerekir. Kaynağınıza bir yedekleme alanı eklerseniz, yedekleme alanını başlatmanız gerekir. Oluşturulan yıkıcı özellik tanımınızı kullanır. Örneğin, aşağıdaki örnek bir konumsal kaydın FirstNamepublicve LastName özelliklerini bildirir, ancak konum parametresini Id ile internalkısıtlar. Kayıtlar ve kayıt yapısı türleri için bu söz dizimini kullanabilirsiniz.

public record Person(string FirstName, string LastName, string Id)
{
    internal string Id { get; init; } = Id;
}

public static void Main()
{
    Person person = new("Nancy", "Davolio", "12345");
    Console.WriteLine(person.FirstName); //output: Nancy

}

Kayıt türünün herhangi bir konumsal özellik bildirmesi gerekmez. Herhangi bir konumsal özelliği olmayan bir kayıt bildirebilir ve aşağıdaki örnekte olduğu gibi diğer alanları ve özellikleri bildirebilirsiniz:

public record Person(string FirstName, string LastName)
{
    public string[] PhoneNumbers { get; init; } = [];
};

Özellikleri standart özellik söz dizimini kullanarak tanımlar ancak erişim değiştiricisini atlarsanız, özellikler örtük olarak privatekullanılır.

Değiştirilemezlik

Konumsal kayıt ve konumsal salt okunur kayıt yapısı yalnızca init özelliklerini bildirir. Konumsal kayıt yapısı okuma-yazma özelliklerini bildirir. Önceki bölümde gösterildiği gibi bu varsayılan değerlerden birini geçersiz kılabilirsiniz.

Veri merkezli bir türün iş parçacığı açısından güvenli olması gerektiğinde veya karma tabloda aynı kalan bir karma koda bağlı olduğunuzda değiştirilemezlik yararlı olabilir. Ancak, değişmezlik tüm veri senaryoları için uygun değildir. Örneğin Entity Framework Core, sabit varlık türleriyle güncelleştirmeyi desteklemez.

Konumsal parametrelerden (record classve readonly record struct) veya erişimcileri belirterek init oluşturulan yalnızca başlatma özellikleri, sığ değişmezliğe sahiptir. Başlatma işleminden sonra, değer türü özelliklerinin değerini veya başvuru türü özelliklerinin başvuruyu değiştiremezsiniz. Ancak, başvuru türü özelliğinin başvurduğu veriler değiştirilebilir. Aşağıdaki örnek, başvuru türü sabit özelliğinin (bu örnekteki bir dizi) içeriğinin değişebilir olduğunu gösterir:

public record Person(string FirstName, string LastName, string[] PhoneNumbers);

public static void Main()
{
    Person person = new("Nancy", "Davolio", new string[1] { "555-1234" });
    Console.WriteLine(person.PhoneNumbers[0]); // output: 555-1234

    person.PhoneNumbers[0] = "555-6789";
    Console.WriteLine(person.PhoneNumbers[0]); // output: 555-6789
}

Kayıt türlerine özgü özellikler derleyici tarafından sentezlenen yöntemler tarafından uygulanır ve bu yöntemlerin hiçbiri nesne durumunu değiştirerek değişmezliği tehlikeye atmaz. Belirtilmediği sürece, sentezlenen yöntemler , record structve readonly record struct bildirimleri için recordoluşturulur.

Değer eşitliği

Eşitlik yöntemlerini geçersiz kılmaz veya değiştirmezseniz, bildirdiğiniz tür eşitliğin nasıl tanımlandığını yönetir:

  • Türler için class , bellekteki aynı nesneye başvuruda bulunan iki nesne eşittir.
  • Türler için struct iki nesne aynı türdeyse ve aynı değerleri depolarsa eşittir.
  • Değiştiricisi record (record class, record structve readonly record struct) olan türler için, aynı türde olan ve aynı değerleri depolayan iki nesne eşittir.

için record struct eşitlik tanımı, ile structaynıdır. Fark, bir structiçin uygulamasının içinde ValueType.Equals(Object) olması ve yansımaya bağlı olmasıdır. Kayıtlar için uygulama derleyici sentezi yapılır ve bildirilen veri üyelerini kullanır.

Bazı veri modelleri için başvuru eşitliği gereklidir. Örneğin Entity Framework Core, kavramsal olarak tek bir varlık için varlık türünün yalnızca bir örneğini kullandığından emin olmak için başvuru eşitliğine bağlıdır. Bu nedenle, kayıtlar ve kayıt yapıları Entity Framework Core'da varlık türleri olarak kullanmak için uygun değildir.

Aşağıdaki örnek, kayıt türlerinin değer eşitliğini gösterir:

public record Person(string FirstName, string LastName, string[] PhoneNumbers);

public static void Main()
{
    var phoneNumbers = new string[2];
    Person person1 = new("Nancy", "Davolio", phoneNumbers);
    Person person2 = new("Nancy", "Davolio", phoneNumbers);
    Console.WriteLine(person1 == person2); // output: True

    person1.PhoneNumbers[0] = "555-1234";
    Console.WriteLine(person1 == person2); // output: True

    Console.WriteLine(ReferenceEquals(person1, person2)); // output: False
}

Değer eşitliğini uygulamak için derleyici aşağıdakiler dahil olmak üzere çeşitli yöntemleri sentezler:

  • geçersiz kılma.Object.Equals(Object) Geçersiz kılma açıkça bildirilirse bu bir hatadır.

    Bu yöntem, her iki parametre de null olmadığında statik yöntemin temeli Object.Equals(Object, Object) olarak kullanılır.

  • Bir virtual, veya sealed, Equals(R? other) burada R kayıt türüdür. Bu yöntem uygular IEquatable<T>. Bu yöntem açıkça bildirilebilir.

  • Kayıt türü bir temel kayıt türünden Basetüretilmişse, . Equals(Base? other) Geçersiz kılma açıkça bildirilirse bu bir hatadır. kendi uygulamanızı Equals(R? other)sağlarsanız, uygulamasını da sağlayın GetHashCode .

  • geçersiz kılma.Object.GetHashCode() Bu yöntem açıkça bildirilebilir.

  • ve !=işleçlerinin == geçersiz kılmaları. İşleçler açıkça bildirilirse bu bir hatadır.

  • Kayıt türü bir temel kayıt türünden türetilmişse, protected override Type EqualityContract { get; };. Bu özellik açıkça bildirilebilir. Daha fazla bilgi için bkz . Devralma hiyerarşilerinde eşitlik.

Kayıt türü açıkça bildirilmesine izin verilen bir sentezlenmiş yöntemin imzası ile eşleşen bir yönteme sahip olduğunda derleyici bir yöntemi sentezlemiyor.

Yok edici mutasyon

Bir örneği bazı değişikliklerle kopyalamanız gerekiyorsa, yıkıcı olmayan mutasyona ulaşmak için bir with ifade kullanabilirsiniz. İfade with , belirtilen özelliklerin ve alanların değiştirildiği mevcut bir kayıt örneğinin kopyası olan yeni bir kayıt örneği oluşturur. Aşağıdaki örnekte gösterildiği gibi değiştirilecek değerleri belirtmek için nesne başlatıcı söz dizimini kullanırsınız:

public record Person(string FirstName, string LastName)
{
    public string[] PhoneNumbers { get; init; }
}

public static void Main()
{
    Person person1 = new("Nancy", "Davolio") { PhoneNumbers = new string[1] };
    Console.WriteLine(person1);
    // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }

    Person person2 = person1 with { FirstName = "John" };
    Console.WriteLine(person2);
    // output: Person { FirstName = John, LastName = Davolio, PhoneNumbers = System.String[] }
    Console.WriteLine(person1 == person2); // output: False

    person2 = person1 with { PhoneNumbers = new string[1] };
    Console.WriteLine(person2);
    // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }
    Console.WriteLine(person1 == person2); // output: False

    person2 = person1 with { };
    Console.WriteLine(person1 == person2); // output: True
}

İfade, with standart özellik söz dizimi kullanılarak oluşturulan konumsal özellikleri veya özellikleri ayarlayabilir. Açıkça bildirilen özelliklerin ifadede değiştirilmesi için bir initwith veya set erişimcisi olmalıdır.

İfadenin with sonucu basit bir kopyadır, yani bir başvuru özelliği için yalnızca bir örneğe başvuru kopyalanır. Hem özgün kayıt hem de kopya aynı örneğe başvuruyla sonuçlanacak.

Bu özelliği türler için uygulamak için record class derleyici bir kopyalama yöntemini ve bir kopya oluşturucuyu sentezler. Sanal kopya yöntemi, kopya oluşturucu tarafından başlatılan yeni bir kayıt döndürür. bir with ifade kullandığınızda, derleyici clone yöntemini çağıran bir kod oluşturur ve ardından ifadede with belirtilen özellikleri ayarlar.

Farklı kopyalama davranışına ihtiyacınız varsa, içinde kendi kopya oluşturucunuzu record classyazabilirsiniz. Bunu yaparsanız, derleyici bir tane sentezlemiyor. Kayıt ise sealedoluşturucunuzu private yapın, aksi takdirde yapınprotected. Derleyici, türler için record struct bir kopya oluşturucuyu sentezlemiyor. Bir tane yazabilirsiniz, ancak derleyici ifadeler için with buna çağrı oluşturmaz. değerleri record struct atamada kopyalanır.

Kopyalama yöntemini geçersiz kılamazsınız ve herhangi bir kayıt türünde adlı Clone bir üye oluşturamazsınız. Kopyalama yönteminin gerçek adı derleyici tarafından oluşturulur.

Görüntüleme için yerleşik biçimlendirme

Kayıt türleri, ortak özelliklerin ve alanların adlarını ve değerlerini görüntüleyen derleyici tarafından oluşturulan ToString bir yönteme sahiptir. ToString yöntemi aşağıdaki biçimde bir dize döndürür:

<kayıt türü adı> { <özellik adı> = <değer>, <özellik adı> = <değer>, ...}

için <value> yazdırılan dize, özelliğin türü için tarafından ToString() döndürülen dizedir. Aşağıdaki örnekte, ChildNames döndürdüğü ToStringSystem.String[]bir System.Arraydeğeridir:

Person { FirstName = Nancy, LastName = Davolio, ChildNames = System.String[] }

Bu özelliği uygulamak için, derleyici türlerde record class bir sanal PrintMembers yöntemi ve geçersiz ToString kılmayı sentezler. Türlerde record struct , bu üye şeklindedir private. Geçersiz kılma, ToString tür adına ve ardından bir açma köşeli ayracına sahip bir nesne oluşturur StringBuilder . Özellik adlarını ve değerlerini eklemek için çağırır PrintMembers ve ardından kapanış köşeli ayracı ekler. Aşağıdaki örnekte, sentezlenen geçersiz kılmanın içerdiğine benzer kod gösterilmektedir:

public override string ToString()
{
    StringBuilder stringBuilder = new StringBuilder();
    stringBuilder.Append("Teacher"); // type name
    stringBuilder.Append(" { ");
    if (PrintMembers(stringBuilder))
    {
        stringBuilder.Append(" ");
    }
    stringBuilder.Append("}");
    return stringBuilder.ToString();
}

kendi uygulamanızı PrintMembers veya geçersiz kılmayı ToString sağlayabilirsiniz. Örnekler, bu makalenin devamında PrintMembers türetilmiş kayıtlarda biçimlendirme bölümünde verilmiştir. C# 10 ve sonraki sürümlerde, uygulamanız ToString derleyicinin sealed türetilmiş kayıtlar için bir ToString uygulamayı sentezlemesini engelleyen değiştiriciyi içerebilir. Tür hiyerarşisi record boyunca tutarlı bir dize gösterimi oluşturabilirsiniz. (Türetilmiş kayıtlarda yine de tüm türetilmiş özellikler için oluşturulmuş bir PrintMembers yöntem vardır.)

Devralma

Bu bölüm yalnızca türler için record class geçerlidir.

Bir kayıt başka bir kayıttan devralabilir. Ancak, bir kayıt bir sınıftan devralamaz ve bir sınıf kayıttan devralamaz.

Türetilmiş kayıt türlerinde konumsal parametreler

Türetilmiş kayıt, temel kayıt birincil oluşturucusunda tüm parametreler için konumsal parametreler bildirir. Temel kayıt bu özellikleri bildirir ve başlatır. Türetilen kayıt bunları gizlemez, ancak yalnızca temel kaydında bildirilmeyen parametreler için özellikler oluşturur ve başlatır.

Aşağıdaki örnek, devralmayı konumsal özellik söz dizimi ile gösterir:

public abstract record Person(string FirstName, string LastName);
public record Teacher(string FirstName, string LastName, int Grade)
    : Person(FirstName, LastName);
public static void Main()
{
    Person teacher = new Teacher("Nancy", "Davolio", 3);
    Console.WriteLine(teacher);
    // output: Teacher { FirstName = Nancy, LastName = Davolio, Grade = 3 }
}

Devralma hiyerarşilerinde eşitlik

Bu bölüm türler için geçerlidir, ancak türler için record class geçerli değildir record struct . İki kayıt değişkeninin eşit olması için çalışma zamanı türünün eşit olması gerekir. İçeren değişkenlerin türleri farklı olabilir. Devralınan eşitlik karşılaştırması aşağıdaki kod örneğinde gösterilmiştir:

public abstract record Person(string FirstName, string LastName);
public record Teacher(string FirstName, string LastName, int Grade)
    : Person(FirstName, LastName);
public record Student(string FirstName, string LastName, int Grade)
    : Person(FirstName, LastName);
public static void Main()
{
    Person teacher = new Teacher("Nancy", "Davolio", 3);
    Person student = new Student("Nancy", "Davolio", 3);
    Console.WriteLine(teacher == student); // output: False

    Student student2 = new Student("Nancy", "Davolio", 3);
    Console.WriteLine(student2 == student); // output: True
}

Örnekte, örnek veya türetilmiş bir türü StudentTeacherolsa bile tüm değişkenler olarak Personbildirilir. Örnekler aynı özelliklere ve aynı özellik değerlerine sahiptir. Ancak student == teacher her ikisi de Person-type değişkenleri olmasına rağmen döndürür False ve student == student2 biri Person değişken, diğeri değişken olmasına Student rağmen döndürürTrue. Eşitlik testi, değişkenin bildirilen türüne değil gerçek nesnenin çalışma zamanı türüne bağlıdır.

Bu davranışı uygulamak için derleyici, kaydın türüyle eşleşen bir nesne döndüren bir Type özelliği sentezlerEqualityContract. eşitlik EqualityContract yöntemlerinin, eşitlik denetimi yaparken nesnelerin çalışma zamanı türünü karşılaştırmasını sağlar. Bir kaydın temel türü ise object, bu özellik olur virtual. Temel tür başka bir kayıt türüyse, bu özellik bir geçersiz kılmadır. Kayıt türü ise sealed, türü olduğundan bu özellik etkili bir şekilde sealed olur sealed.

Kod türetilmiş bir türün iki örneğini karşılaştırdığında, sentezlenen eşitlik yöntemleri temel ve türetilmiş türlerin tüm veri üyelerini eşitlik açısından denetler. Sentezlenen GetHashCode yöntem, temel tür ve türetilmiş kayıt türünde bildirilen tüm veri üyelerinden yöntemini kullanır GetHashCode . ' record nin veri üyeleri, otomatik olarak tanımlanan tüm özellikler için bildirilen tüm alanları ve derleyici tarafından sentezlenen yedekleme alanını içerir.

with türetilmiş kayıtlardaki ifadeler

bir with ifadenin sonucu, ifadenin işleneni ile aynı çalışma zamanı türüne sahiptir. Çalışma zamanı türünün tüm özellikleri kopyalanır, ancak aşağıdaki örnekte gösterildiği gibi yalnızca derleme zamanı türünün özelliklerini ayarlayabilirsiniz:

public record Point(int X, int Y)
{
    public int Zbase { get; set; }
};
public record NamedPoint(string Name, int X, int Y) : Point(X, Y)
{
    public int Zderived { get; set; }
};

public static void Main()
{
    Point p1 = new NamedPoint("A", 1, 2) { Zbase = 3, Zderived = 4 };

    Point p2 = p1 with { X = 5, Y = 6, Zbase = 7 }; // Can't set Name or Zderived
    Console.WriteLine(p2 is NamedPoint);  // output: True
    Console.WriteLine(p2);
    // output: NamedPoint { X = 5, Y = 6, Zbase = 7, Name = A, Zderived = 4 }

    Point p3 = (NamedPoint)p1 with { Name = "B", X = 5, Y = 6, Zbase = 7, Zderived = 8 };
    Console.WriteLine(p3);
    // output: NamedPoint { X = 5, Y = 6, Zbase = 7, Name = B, Zderived = 8 }
}

PrintMembers türetilmiş kayıtlarda biçimlendirme

Türetilmiş kayıt türünün sentezlenmiş PrintMembers yöntemi temel uygulamayı çağırır. Sonuç, aşağıdaki örnekte gösterildiği gibi hem türetilmiş hem de temel türlerdeki tüm genel özelliklerin ToString ve alanların çıktıya dahil edilmiş olmasıdır:

public abstract record Person(string FirstName, string LastName);
public record Teacher(string FirstName, string LastName, int Grade)
    : Person(FirstName, LastName);
public record Student(string FirstName, string LastName, int Grade)
    : Person(FirstName, LastName);

public static void Main()
{
    Person teacher = new Teacher("Nancy", "Davolio", 3);
    Console.WriteLine(teacher);
    // output: Teacher { FirstName = Nancy, LastName = Davolio, Grade = 3 }
}

Yönteminin kendi uygulamasını PrintMembers sağlayabilirsiniz. Bunu yaparsanız aşağıdaki imzayı kullanın:

  • 'den türetilen bir sealed kayıt için (temel kayıt bildirmez): private bool PrintMembers(StringBuilder builder);object
  • Başka bir kayıttan türetilen bir sealed kayıt için (kapsayan türün olduğunu sealed, dolayısıyla yönteminin etkili sealedolduğunu unutmayın): protected override bool PrintMembers(StringBuilder builder);
  • Olmayan ve nesneden türetilen bir kayıt sealed için: protected virtual bool PrintMembers(StringBuilder builder);
  • Olmayan ve başka bir kayıttan sealed türetilen bir kayıt için: protected override bool PrintMembers(StringBuilder builder);

Bir tane nesneden türetilen kayıt türü için, diğeri de başka bir kayıttan türetilen kayıt türü için olmak üzere sentezlenmiş PrintMembers yöntemlerin yerini alan bir kod örneği aşağıda verilmiştir:

public abstract record Person(string FirstName, string LastName, string[] PhoneNumbers)
{
    protected virtual bool PrintMembers(StringBuilder stringBuilder)
    {
        stringBuilder.Append($"FirstName = {FirstName}, LastName = {LastName}, ");
        stringBuilder.Append($"PhoneNumber1 = {PhoneNumbers[0]}, PhoneNumber2 = {PhoneNumbers[1]}");
        return true;
    }
}

public record Teacher(string FirstName, string LastName, string[] PhoneNumbers, int Grade)
    : Person(FirstName, LastName, PhoneNumbers)
{
    protected override bool PrintMembers(StringBuilder stringBuilder)
    {
        if (base.PrintMembers(stringBuilder))
        {
            stringBuilder.Append(", ");
        };
        stringBuilder.Append($"Grade = {Grade}");
        return true;
    }
};

public static void Main()
{
    Person teacher = new Teacher("Nancy", "Davolio", new string[2] { "555-1234", "555-6789" }, 3);
    Console.WriteLine(teacher);
    // output: Teacher { FirstName = Nancy, LastName = Davolio, PhoneNumber1 = 555-1234, PhoneNumber2 = 555-6789, Grade = 3 }
}

Not

C# 10 ve sonraki sürümlerde, bir temel kayıt yöntemi mühürlediğinde ToString bile derleyici türetilmiş kayıtlarda sentezlenirPrintMembers. Kendi uygulamanızı PrintMembersda oluşturabilirsiniz.

Türetilmiş kayıtlarda yapısızlaştırma davranışı

Deconstruct Türetilmiş bir kaydın yöntemi, derleme zamanı türünün tüm konumsal özelliklerinin değerlerini döndürür. Değişken türü bir temel kayıtsa, nesne türetilen türe dönüştürülmediği sürece yalnızca temel kayıt özellikleri yok edilir. Aşağıdaki örnek, türetilmiş bir kayıtta bir yıkıcı çağırmayı gösterir.

public abstract record Person(string FirstName, string LastName);
public record Teacher(string FirstName, string LastName, int Grade)
    : Person(FirstName, LastName);
public record Student(string FirstName, string LastName, int Grade)
    : Person(FirstName, LastName);

public static void Main()
{
    Person teacher = new Teacher("Nancy", "Davolio", 3);
    var (firstName, lastName) = teacher; // Doesn't deconstruct Grade
    Console.WriteLine($"{firstName}, {lastName}");// output: Nancy, Davolio

    var (fName, lName, grade) = (Teacher)teacher;
    Console.WriteLine($"{fName}, {lName}, {grade}");// output: Nancy, Davolio, 3
}

Genel kısıtlamalar

anahtar record sözcüğü, bir veya struct türü için class değiştiricidir. Değiştiricinin record eklenmesi, bu makalenin önceki bölümlerinde açıklanan davranışı içerir. Kayıt türü gerektiren genel bir kısıtlama yoktur. A record class , kısıtlamayı class karşılar. A record struct , kısıtlamayı struct karşılar. Daha fazla bilgi için bkz . Tür parametrelerindeki kısıtlamalar.

C# dili belirtimi

Daha fazla bilgi için C# dil belirtiminin Sınıflar bölümüne bakın.

Bu özellikler hakkında daha fazla bilgi için aşağıdaki özellik teklifi notlarını inceleyin:

Ayrıca bkz.