Úvod do typů záznamů v jazyce C#
Záznam v jazyce C# je třída nebo struktura, která poskytuje speciální syntaxi a chování pro práci s datovými modely. record
Modifikátor dává kompilátoru pokyn, aby syntetizoval členy, které jsou užitečné pro typy, jejichž primární role ukládá data. Mezi tyto členy patří přetížení ToString() a členy, které podporují rovnost hodnot.
Kdy použít záznamy
Zvažte použití záznamu místo třídy nebo struktury v následujících scénářích:
- Chcete definovat datový model, který závisí na rovnosti hodnot.
- Chcete definovat typ, pro který objekty jsou neměnné.
Rovnost hodnot
Pro záznamy rovnost hodnot znamená, že dvě proměnné typu záznamu jsou stejné, pokud se typy shodují a všechny hodnoty vlastností a polí se shodují. Pro jiné odkazové typy, jako jsou třídy, rovnost znamená rovnost odkazů. To znamená, že dvě proměnné typu třídy jsou stejné, pokud odkazují na stejný objekt. Metody a operátory, které určují rovnost dvou instancí záznamů, používají rovnost hodnot.
Ne všechny datové modely dobře fungují s rovností hodnot. Například Entity Framework Core závisí na rovnosti odkazů, aby se zajistilo, že používá pouze jednu instanci typu entity pro to, co je koncepčně jedna entita. Z tohoto důvodu nejsou typy záznamů vhodné pro použití jako typy entit v Entity Framework Core.
Neměnitelnost
Neměnný typ je typ, který vám brání ve změně jakékoli vlastnosti nebo hodnoty polí objektu po vytvoření instance. Neměnnost může být užitečná v případě, že potřebujete typ bezpečný pro přístup z více vláken nebo v závislosti na zbývajícím hashovacím kódu v tabulce hash. Záznamy poskytují stručnou syntaxi pro vytváření a práci s neměnnými typy.
Neměnnost není vhodná pro všechny scénáře dat. Entity Framework Core například nepodporuje aktualizaci pomocí neměnných typů entit.
Jak se záznamy liší od tříd a struktur
Stejnou syntaxi, která deklaruje a vytváří instance tříd nebo struktur, lze použít se záznamy. Stačí nahradit class
klíčové slovo slovem record
, nebo použít record struct
místo struct
. Stejně tak je stejná syntaxe pro vyjádření vztahů dědičnosti podporována třídami záznamů. Záznamy se liší od tříd následujícími způsoby:
- Poziční parametry v primárním konstruktoru můžete použít k vytvoření a vytvoření instance typu s neměnnými vlastnostmi.
- Stejné metody a operátory, které označují rovnost nebo nerovnost ve třídách (například Object.Equals(Object) a), označují rovnost hodnot nebo nerovnost
==
v záznamech. - Pomocí výrazu
with
můžete vytvořit kopii neměnného objektu s novými hodnotami ve vybraných vlastnostech. - Metoda záznamu
ToString
vytvoří formátovaný řetězec, který zobrazuje název typu objektu a názvy a hodnoty všech jeho veřejných vlastností. - Záznam může dědit z jiného záznamu. Záznam nemůže dědit z třídy a třída nemůže dědit ze záznamu.
Struktury záznamů se liší od struktur v tom, že kompilátor syntetizuje metody rovnosti a ToString
. Kompilátor syntetizuje metodu Deconstruct
pro struktury pozičních záznamů.
Kompilátor syntetizuje veřejnou inicializační vlastnost pro každý primární konstruktor parametr v objektu record class
. V kompilátoru record struct
syntetizuje veřejnou vlastnost pro čtení i zápis. Kompilátor nevytvoří vlastnosti pro parametry primárního konstruktoru v class
a struct
typech, které neobsahují record
modifikátor.
Příklady
Následující příklad definuje veřejný záznam, který používá poziční parametry k deklaraci a vytvoření instance záznamu. Potom vytiskne hodnoty názvu a vlastnosti typu:
public record Person(string FirstName, string LastName);
public static class Program
{
public static void Main()
{
Person person = new("Nancy", "Davolio");
Console.WriteLine(person);
// output: Person { FirstName = Nancy, LastName = Davolio }
}
}
Následující příklad ukazuje rovnost hodnot v záznamech:
public record Person(string FirstName, string LastName, string[] PhoneNumbers);
public static class Program
{
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
}
}
Následující příklad ukazuje použití with
výrazu ke zkopírování neměnného objektu a změně jedné z vlastností:
public record Person(string FirstName, string LastName)
{
public required string[] PhoneNumbers { get; init; }
}
public class Program
{
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
}
}
Další informace najdete v tématu Záznamy (referenční dokumentace jazyka C#).
Specifikace jazyka C#
Další informace najdete v tématu Specifikace jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro