Rekordok (C#-referencia)
A módosítóval record
olyan referenciatípust definiálhat, amely beépített funkciókat biztosít az adatok beágyazásához. A C# 10 lehetővé teszi, hogy a record class
szintaxis szinonimaként egyértelműsítsen egy referenciatípust, és record struct
hasonló funkcionalitású értéktípust definiáljon.
Amikor egy rekordon elsődleges konstruktort deklarál, a fordító nyilvános tulajdonságokat hoz létre az elsődleges konstruktor paramétereihez. A rekord elsődleges konstruktorparamétereit pozícióparamétereknek nevezzük. A fordító olyan pozíciótulajdonságokat hoz létre, amelyek tükrözik az elsődleges konstruktort vagy a pozícióparamétereket. A fordító nem szintetizálja az elsődleges konstruktorparaméterek tulajdonságait olyan típusok esetében, amelyek nem rendelkeznek a record
módosítóval.
Az alábbi két példa (vagy record class
) referenciatípust mutat be record
:
public record Person(string FirstName, string LastName);
public record Person
{
public required string FirstName { get; init; }
public required string LastName { get; init; }
};
Az alábbi két példa az értéktípusokat mutatja be 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; }
}
A következő rekordokat is létrehozhatja mutable tulajdonságokkal és mezőkkel:
public record Person
{
public required string FirstName { get; set; }
public required string LastName { get; set; }
};
A rekordstruktúra is módosítható, mind a pozicionálási, mind a rekordstruktúra pozícióparaméterek nélkül:
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; }
}
Bár a rekordok módosíthatók, elsősorban nem módosítható adatmodellek támogatására szolgálnak. A rekordtípus a következő funkciókat kínálja:
- Rövid szintaxis nem módosítható tulajdonságokkal rendelkező referenciatípus létrehozásához
- Az adatcentrikus referenciatípushoz használható beépített viselkedés:
- Öröklési hierarchiák támogatása
Az előző példák néhány különbséget mutatnak a hivatkozási típusok és az érték típusú rekordok között:
- A
record
vagy egyrecord class
deklarál egy referenciatípust. Aclass
kulcsszó nem kötelező, de érthetőbbé teheti az olvasókat. Egyrecord struct
értéktípust deklarál. - A pozíciótulajdonságok nem módosíthatók az a
record class
és areadonly record struct
. Egy .record struct
A cikk további része mind a típusokat, mind a típusokat record class
record struct
ismerteti. A különbségek részletesek az egyes szakaszokban. Az a és egy record struct
közötti döntéshez class
hasonló és hasonló döntés között kell dönteniestruct
.record class
A kifejezésrekord az összes rekordtípusra vonatkozó viselkedés leírására szolgál. record class
Vagy record struct
olyan viselkedés leírására szolgál, amely csak a strustruktúra- vagy osztálytípusokra vonatkozik. A record struct
típus a C# 10-ben lett bevezetve.
Tulajdonságdefiníció pozíciószintaxisa
A helymeghatározó paraméterekkel deklarálhatja egy rekord tulajdonságait, és inicializálhatja a tulajdonságértékeket egy példány létrehozásakor:
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 }
}
Ha a tulajdonságdefiníció pozíciószintaxisát használja, a fordító a következőket hozza létre:
- A rekorddeklarációban megadott minden egyes pozícióparaméterhez tartozó nyilvános automatikus tulajdonság.
- Típusok és típusok esetén
record
: Csak init-only tulajdonság.readonly record struct
- Típusok esetén
record struct
: Írásvédett tulajdonság.
- Típusok és típusok esetén
- Elsődleges konstruktor, amelynek paraméterei megegyeznek a rekorddeklarációban szereplő pozícióparaméterekkel.
- Rekordstruktúratípusok esetén egy paraméter nélküli konstruktor, amely az egyes mezőket az alapértelmezett értékre állítja.
- A
Deconstruct
rekorddeklarációban megadott minden egyes pozícióparaméter paraméterével rendelkezőout
metódus. A metódus a pozíciószintaxissal definiált tulajdonságokat dekonstruálja; figyelmen kívül hagyja a standard tulajdonságszintaxissal definiált tulajdonságokat.
Érdemes lehet attribútumokat hozzáadni ezekhez az elemekhez, amelyeket a fordító a rekorddefinícióból hoz létre. A pozíciórekord tulajdonságaira alkalmazott bármely attribútumhoz hozzáadhat célhelyet . Az alábbi példa a System.Text.Json.Serialization.JsonPropertyNameAttribute rekord minden tulajdonságára Person
vonatkozik. A property:
cél azt jelzi, hogy az attribútum a fordító által létrehozott tulajdonságra lesz alkalmazva. Más értékek az field:
attribútum alkalmazása a mezőre, és param:
az attribútum alkalmazása a paraméterre.
/// <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);
Az előző példa azt is bemutatja, hogyan hozhat létre XML-dokumentációs megjegyzéseket a rekordhoz. A címkét hozzáadhatja az <param>
elsődleges konstruktor paramétereinek dokumentációjának hozzáadásához.
Ha az automatikusan létrehozott tulajdonságdefiníció nem az, amit szeretne, azonos nevű saját tulajdonságot is definiálhat. Előfordulhat például, hogy módosítani szeretné az akadálymentességet vagy a módosíthatóságot, vagy implementációt szeretne biztosítani a tartozékhoz vagy set
a get
tartozékhoz. Ha a tulajdonságot a forrásban deklarálja, inicializálnia kell azt a rekord pozícióparaméteréből. Ha a tulajdonság autoimplementált tulajdonság, inicializálnia kell a tulajdonságot. Ha egy háttérmezőt ad hozzá a forráshoz, inicializálnia kell a háttérmezőt. A létrehozott dekonstruktor a tulajdonságdefiníciót használja. Az alábbi példa például egy pozíciórekord public
tulajdonságait deklarálja LastName
FirstName
, de a pozícióparamétert a Id
következőre internal
korlátozza. Ezt a szintaxist rekordokhoz és rekordstruktúratípusokhoz használhatja.
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
}
A rekordtípusoknak nem kell helytulajdonságokat deklarálniuk. A rekordokat pozíciótulajdonságok nélkül deklarálhatja, és deklarálhat más mezőket és tulajdonságokat is, ahogyan az alábbi példában is látható:
public record Person(string FirstName, string LastName)
{
public string[] PhoneNumbers { get; init; } = [];
};
Ha a tulajdonságokat standard tulajdonságszintaxissal definiálja, de kihagyja a hozzáférési módosító használatát, a tulajdonságok implicit módon private
lesznek.
Módosíthatatlanság
A pozíciórekord és a pozícióalapú írásvédett rekord a csak init-only tulajdonságok deklarálására utasítja . A pozicionált rekordstruktúra írási-olvasási tulajdonságokat deklarál. Felülbírálhatja bármelyik alapértelmezett beállítást, ahogy az előző szakaszban is látható.
A nem módosíthatóság akkor lehet hasznos, ha adatközpontú típusra van szükség a szálbiztosság érdekében, vagy ha egy kivonatkód ugyanaz marad a kivonattáblában. A nem módosíthatóság azonban nem minden adatforgatókönyv esetében megfelelő. Az Entity Framework Core például nem támogatja a nem módosítható entitástípusok frissítését.
A csak init-only tulajdonságok, függetlenül attól, hogy a pozícióparaméterekből (record class
és readonly record struct
) vagy a tartozékok megadásával init
lettek létrehozva, sekély megváltoztathatatlansággal rendelkeznek. Az inicializálás után nem módosíthatja az érték típusú tulajdonságok értékét vagy a referencia típusú tulajdonságok hivatkozását. A referencia típusú tulajdonság által hivatkozott adatok azonban módosíthatók. Az alábbi példa azt mutatja be, hogy egy referencia típusú nem módosítható tulajdonság (ebben az esetben egy tömb) tartalma nem módosítható:
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
}
A rekordtípusokra jellemző funkciókat fordító-szintetizált metódusok implementálják, és egyik módszer sem veszélyezteti az objektumállapot módosításával a megváltoztathatatlanságot. Ha nincs megadva, a rendszer létrehozza a szintetizált metódusokat a , record struct
és readonly record struct
a deklarációkhozrecord
.
Értékegyenlőség
Ha nem bírálja felül vagy cseréli le az egyenlőségi módszereket, a deklarált típus szabályozza az egyenlőség definícióját:
- A típusok esetében
class
két objektum egyenlő, ha ugyanarra az objektumra hivatkoznak a memóriában. - A típusok esetében
struct
két objektum egyenlő, ha azonos típusúak, és ugyanazokat az értékeket tárolják. - A módosítóval (
record class
ésrecord struct
readonly record struct
) rendelkezőrecord
típusok esetében két objektum egyenlő, ha azonos típusúak, és ugyanazokat az értékeket tárolják.
Az egyenlőség record struct
definíciója megegyezik struct
a . A különbség az, hogy egy struct
, a megvalósítás van, ValueType.Equals(Object) és támaszkodik tükröződés. A rekordok esetében a implementáció szintetizált fordító, és a deklarált adattagokat használja.
Egyes adatmodellekhez referenciaegyenlőség szükséges. Az Entity Framework Core például a referenciaegyenlőségtől függ annak biztosítása érdekében, hogy egy entitástípusnak csak egy példányát használja az egy elméletileg egy entitáshoz. Emiatt a rekordok és a rekordstruktúra nem megfelelő entitástípusokként való használatra az Entity Framework Core-ban.
Az alábbi példa a rekordtípusok értékegyenlőségét szemlélteti:
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
}
Az értékegyenlőség megvalósítása érdekében a fordító több módszert szintetizál, többek között a következőket:
A Object.Equals(Object)felülbírálása. Hiba, ha a felülbírálás explicit módon van deklarálva.
Ez a módszer a statikus módszer alapja Object.Equals(Object, Object) , ha mindkét paraméter nem null értékű.
A
virtual
, vagysealed
,Equals(R? other)
aholR
a rekord típusa. Ez a metódus implementálja a IEquatable<T>. Ez a módszer explicit módon deklarálható.Ha a rekordtípus egy alaprekordtípusból
Base
származik,Equals(Base? other)
akkor . Hiba, ha a felülbírálás explicit módon van deklarálva. Ha a saját implementációjátEquals(R? other)
adja meg, adja meg a megvalósítástGetHashCode
is.A Object.GetHashCode()felülbírálása. Ez a módszer explicit módon deklarálható.
Operátorok
==
felülbírálása és!=
. Hiba, ha az operátorok explicit módon vannak deklarálva.Ha a rekordtípus egy alaprekordtípusból származik,
protected override Type EqualityContract { get; };
akkor. Ez a tulajdonság explicit módon deklarálható. További információ: Egyenlőség az öröklési hierarchiákban.
A fordító nem szintetizál metódust, ha egy rekordtípus olyan metódussal rendelkezik, amely megfelel egy explicit módon deklarálható szintetizált metódus aláírásának.
Nem strukturált mutáció
Ha módosításokkal kell másolnia egy példányt, egy kifejezéssel with
nem strukturált mutációt érhet el. Egy with
kifejezés létrehoz egy új rekordpéldányt, amely egy meglévő rekordpéldány másolata, a megadott tulajdonságokkal és mezőkkel együtt. Az objektum inicializáló szintaxisával adja meg a módosítani kívánt értékeket, ahogy az alábbi példában is látható:
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
}
A with
kifejezés beállíthat pozíciótulajdonságokat vagy standard tulajdonságszintaxissal létrehozott tulajdonságokat. A explicit módon deklarált tulajdonságoknak egy kifejezésben módosítani kell egy init
vagy set
több tartozékot with
.
A kifejezés eredménye with
egy sekély másolat, ami azt jelenti, hogy egy referenciatulajdonság esetében csak a példányra mutató hivatkozás lesz másolva. Az eredeti rekord és a másolat is ugyanarra a példányra mutató hivatkozással végződik.
A szolgáltatás típusokhoz való record class
implementálásához a fordító egy klónozási módszert és egy másolási konstruktort szintetizál. A virtuális klónozási módszer egy új rekordot ad vissza, amelyet a másolási konstruktor inicializált. Kifejezés használatakor a fordító létrehoz egy with
kódot, amely meghívja a klónozási metódust, majd beállítja a with
kifejezésben megadott tulajdonságokat.
Ha más másolási viselkedésre van szüksége, saját példánykonstruktort írhat egy record class
. Ha ezt teszi, a fordító nem szintetizál egyet. Állítsa be a konstruktort private
, ha a rekord az sealed
, ellenkező esetben készítse el protected
. A fordító nem szintetizálja a példánykonstruktort a típusok esetében record struct
. Írhat egyet, de a fordító nem generál rá hívásokat kifejezésekhez with
. A program kimásolja a record struct
hozzárendelés értékeit.
Nem bírálhatja felül a klónozási módszert, és nem hozhat létre semmilyen rekordtípusban elnevezett Clone
tagot. A klónozási módszer tényleges neve fordító által generált.
Beépített formázás a megjelenítéshez
A rekordtípusok egy fordító által létrehozott ToString metódussal rendelkeznek, amely megjeleníti a nyilvános tulajdonságok és mezők nevét és értékeit. A ToString
metódus a következő formátumú sztringet adja vissza:
<rekordtípus neve> { <tulajdonság neve> = <érték>, <tulajdonságnév> = <érték>, ...}
A kinyomtatott sztring <value>
a tulajdonság típusának visszaadott sztringje ToString() . Az alábbi példában ChildNames
egy System.Array, ahol ToString
a következőt adja System.String[]
vissza:
Person { FirstName = Nancy, LastName = Davolio, ChildNames = System.String[] }
A funkció implementálásához a fordító típusokban record class
szintetizál egy virtuális PrintMembers
metódust és egy felülbírálást ToString . Típusok esetén record struct
ez a tag a private
.
A ToString
felülbírálás létrehoz egy StringBuilder objektumot a típusnévvel, amelyet egy nyitó zárójel követ. Meghívja PrintMembers
a tulajdonságnevek és értékek hozzáadását, majd hozzáadja a záró zárójelet. Az alábbi példa a szintetizált felülbíráláshoz hasonló kódot mutat be:
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();
}
Saját implementációt PrintMembers
vagy felülbírálást ToString
is megadhat. Példákat a cikk későbbi részében, a PrintMembers
származtatott rekordok szakaszában talál. A C# 10-ben és újabb verzióiban előfordulhat, hogy a sealed
módosító implementációja ToString
megakadályozza, hogy a fordító bármilyen származtatott rekord implementációját szintetizáljaToString
. A típusok hierarchiája record
során konzisztens sztring-reprezentációt hozhat létre. (A származtatott rekordokban továbbra is létre van hozva egy PrintMembers
metódus az összes származtatott tulajdonsághoz.)
Öröklődés
Ez a szakasz csak a típusokra record class
vonatkozik.
Egy rekord örökölhet egy másik rekordot. Egy rekord azonban nem örökölhető egy osztálytól, és az osztály nem örökölhet rekordból.
Pozícióparaméterek származtatott rekordtípusokban
A származtatott rekord az alaprekord elsődleges konstruktorának összes paraméteréhez deklarálja a pozícióparamétereket. Az alaprekord deklarálja és inicializálja ezeket a tulajdonságokat. A származtatott rekord nem rejti el őket, csak az alaprekordban nem deklarált paraméterek tulajdonságait hozza létre és inicializálja.
Az alábbi példa a pozíciótulajdonság szintaxisával szemlélteti az öröklést:
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 }
}
Egyenlőség az öröklési hierarchiákban
Ez a szakasz a típusokra record class
vonatkozik, a típusokra azonban nem record struct
. Ahhoz, hogy két rekordváltozó egyenlő legyen, a futási idő típusának egyenlőnek kell lennie. A változók típusai eltérőek lehetnek. Az örökölt egyenlőség összehasonlítását az alábbi példakód szemlélteti:
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
}
A példában minden változó deklarálva Person
van, még akkor is, ha a példány egy vagy több származtatott típusTeacher
Student
. A példányok ugyanazokkal a tulajdonságokkal és tulajdonságértékekkel rendelkeznek. De student == teacher
mindkettő Person
False
-típusú változó, és student == student2
visszaadjaTrue
, bár az Person
egyik változó, a másik pedig változóStudent
. Az egyenlőségi teszt a tényleges objektum futásidejű típusától függ, nem a változó deklarált típusától.
Ennek a viselkedésnek a megvalósítása érdekében a fordító szintetizál egy EqualityContract
tulajdonságot, amely egy Type olyan objektumot ad vissza, amely megfelel a rekord típusának. Ez EqualityContract
lehetővé teszi, hogy az egyenlőségi metódusok összehasonlítsák az objektumok futásidejű típusát, amikor egyenlőséget keresnek. Ha egy rekord alaptípusa , object
akkor ez a tulajdonság .virtual
Ha az alaptípus egy másik rekordtípus, ez a tulajdonság felülbírálás. Ha a rekord típusa az sealed
, akkor ez a tulajdonság gyakorlatilag sealed
azért van, mert a típus az sealed
.
Ha a kód egy származtatott típus két példányát hasonlítja össze, a szintetizált egyenlőségi módszerek ellenőrzik az alap és a származtatott típusok összes adattagját az egyenlőség szempontjából. A szintetizált GetHashCode
metódus az alaptípusban és a GetHashCode
származtatott rekordtípusban deklarált összes adattag metódusát használja. Az adattagok tartalmazzák az record
összes deklarált mezőt és a fordító által szintetizált háttérmezőt az automatikusan létrehozott tulajdonságokhoz.
with
kifejezések származtatott rekordokban
A kifejezés eredménye with
ugyanazzal a futásidejű típussal rendelkezik, mint a kifejezés operandusa. A futtatási idő típusának összes tulajdonsága másolásra kerül, de csak a fordítási idő típusú tulajdonságok állíthatók be, ahogyan az alábbi példa mutatja:
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
formázás származtatott rekordokban
A származtatott rekordtípus szintetizált PrintMembers
metódusa meghívja az alap implementációt. Az eredmény az, hogy a kimenet tartalmazza ToString
a származtatott és az alaptípusú összes nyilvános tulajdonságot és mezőt, ahogyan az az alábbi példában látható:
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 }
}
A metódus saját implementációját PrintMembers
is megadhatja. Ha így tesz, használja a következő aláírást:
sealed
Olyan rekord esetében, amely származikobject
(nem deklarál alaprekordot):private bool PrintMembers(StringBuilder builder)
;- Egy
sealed
másik rekordból származó rekord esetében (vegye figyelembe, hogy a beágyazási típussealed
az, tehát a módszer hatékonyansealed
):protected override bool PrintMembers(StringBuilder builder)
; - Olyan rekord esetén, amely nem
sealed
objektumból származik:protected virtual bool PrintMembers(StringBuilder builder);
- Olyan rekord esetén, amely nem
sealed
egy másik rekordból származik:protected override bool PrintMembers(StringBuilder builder);
Íme egy példa a szintetizált PrintMembers
metódusokat lecserélő kódra, az egyik az objektumból származó rekordtípusra, a másik pedig egy másik rekordból származó rekordtípusra:
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 }
}
Feljegyzés
A C# 10-es és újabb verzióiban a fordító származtatott rekordokban szintetizál PrintMembers
, még akkor is, ha egy alaprekord lezárta a metódust ToString
. A saját implementációját is létrehozhatja PrintMembers
.
Dekonstruktor viselkedése származtatott rekordokban
A Deconstruct
származtatott rekord metódusa a fordítási idő típusú összes pozíciótulajdonság értékét adja vissza. Ha a változótípus alaprekord, csak az alaprekord tulajdonságai lesznek dekonstruálva, kivéve, ha az objektumot a származtatott típusra öntötték. Az alábbi példa egy dekonstruktor meghívását mutatja be egy származtatott rekordon.
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
}
Általános korlátozások
A record
kulcsszó egy vagy struct
több típus módosítójaclass
. A record
módosító hozzáadása magában foglalja a cikkben korábban ismertetett viselkedést. Nincs általános korlátozás, amely megköveteli, hogy egy típus rekord legyen. Az A record class
megfelel a kényszernek class
. Az A record struct
megfelel a kényszernek struct
. További információ: Típusparaméterek korlátozásai.
C# nyelvspecifikáció
További információkért lásd a C#-nyelv specifikációjának Osztályok szakaszát.
További információ ezekről a funkciókról:
Lásd még
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: