Vlastnosti (Průvodce programováním v C#)
Vlastnost je člen, který poskytuje flexibilní mechanismus pro čtení, zápis nebo výpočet hodnoty datového pole. Vlastnosti se zobrazují jako veřejné datové členy, ale implementují se jako speciální metody označované jako přístupové objekty. Tato funkce umožňuje volajícím snadno přistupovat k datům a stále pomáhá zvýšit bezpečnost a flexibilitu dat. Syntaxe vlastností je přirozené rozšíření polí. Pole definuje umístění úložiště:
public class Person
{
public string? FirstName;
// Omitted for brevity.
}
Automaticky implementované vlastnosti
Definice vlastnosti obsahuje deklarace pro get
objekt a set
přístup, který načte a přiřadí hodnotu této vlastnosti:
public class Person
{
public string? FirstName { get; set; }
// Omitted for brevity.
}
Předchozí příklad ukazuje automaticky implementovanou vlastnost. Kompilátor vygeneruje skryté záložní pole pro vlastnost. Kompilátor také implementuje tělo get
a set
přístupové objekty. Všechny atributy se použijí na automaticky implementovanou vlastnost. Atribut můžete použít u pole backingu vygenerovaného kompilátorem zadáním field:
značky atributu.
Vlastnost můžete inicializovat na jinou hodnotu než výchozí nastavením hodnoty za pravou závorkou vlastnosti. Můžete preferovat počáteční hodnotu vlastnosti FirstName
, aby byla prázdný řetězec, a ne null
. Určíte, jak je znázorněno v následujícím kódu:
public class Person
{
public string FirstName { get; set; } = string.Empty;
// Omitted for brevity.
}
Vlastnosti zálohované pole
V jazyce C# 13 můžete do přístupové vlastnosti přidat ověření nebo jinou logiku pomocí funkce Preview klíčového field
slova. Klíčové field
slovo přistupuje k syntetizovanému záložnímu poli kompilátoru pro vlastnost. Umožňuje psát přístupové objekty vlastností bez explicitního deklarování samostatného záložního pole.
public class Person
{
public string? FirstName
{
get;
set => field = value.Trim();
}
// Omitted for brevity.
}
Důležité
Klíčové field
slovo je funkce preview v jazyce C# 13. Pokud chcete použít field
kontextové klíčové slovo, musíte použít .NET 9 a nastavit prvek <LangVersion>
do preview
souboru projektu.
Měli byste být opatrní pomocí funkce klíčového field
slova ve třídě, která má pole s názvem field
. Nové field
klíčové slovo stínuje pole pojmenované field
v oboru přístupového objektu vlastnosti. Můžete změnit název field
proměnné nebo pomocí @
tokenu odkazovat na field
identifikátor jako @field
. Další informace najdete ve specifikaci funkce pro field
klíčové slovo.
Požadované vlastnosti
Předchozí příklad umožňuje volajícímu Person
vytvořit pomocí výchozího konstruktoru bez nastavení FirstName
vlastnosti. Vlastnost změnila typ na řetězec s možnou hodnotou null. Počínaje jazykem C# 11 můžete vyžadovat , aby volající nastavili vlastnost:
public class Person
{
public Person() { }
[SetsRequiredMembers]
public Person(string firstName) => FirstName = firstName;
public required string FirstName { get; init; }
// Omitted for brevity.
}
Předchozí kód provede dvě změny Person
třídy. Nejprve deklarace FirstName
vlastnosti zahrnuje required
modifikátor. To znamená, že jakýkoli kód, který vytvoří novouPerson
, musí nastavit tuto vlastnost pomocí inicializátoru objektů. Za druhé, konstruktor, který přebírá firstName
parametr má System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute atribut. Tento atribut informuje kompilátor, že tento konstruktor nastaví všechny required
členy. Volající používající tento konstruktor nejsou potřeba k nastavení required
vlastností pomocí inicializátoru objektů.
Důležité
Nezaměňujte required
s nenulovou hodnotou. Je platné nastavit required
vlastnost na null
hodnotu nebo default
. Pokud je typ nenulový, například string
v těchto příkladech, kompilátor vydá upozornění.
var aPerson = new Person("John");
aPerson = new Person{ FirstName = "John"};
// Error CS9035: Required member `Person.FirstName` must be set:
//aPerson2 = new Person();
Definice textu výrazu
Přístupové objekty vlastností se často skládají z jednořádkových příkazů. Přístupové objekty přiřazují nebo vrací výsledek výrazu. Tyto vlastnosti můžete implementovat jako členy s body výrazu. Definice těla výrazu se skládají z tokenu =>
následovaného výrazem, ke kterému se má přiřadit nebo načíst z vlastnosti.
Vlastnosti jen pro get
čtení mohou implementovat přístup jako člen typu výraz bodied. Následující příklad implementuje vlastnost jen Name
pro čtení jako výraz-bodied člen:
public class Person
{
public Person() { }
[SetsRequiredMembers]
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public required string FirstName { get; init; }
public required string LastName { get; init; }
public string Name => $"{FirstName} {LastName}";
// Omitted for brevity.
}
Vlastnost Name
je vypočítaná vlastnost. Neexistuje žádné záložní pole pro Name
. Tato vlastnost ji pokaždé vypočítá.
Řízení přístupu
Předchozí příklady ukázaly vlastnosti čtení a zápisu. Můžete také vytvořit vlastnosti jen pro čtení nebo nastavit různou přístupnost sady a získat přístupové objekty. Předpokládejme, že vaše Person
třída by měla povolit pouze změnu hodnoty FirstName
vlastnosti z jiných metod třídy. Přístup k sadě private
můžete nastavit tak, aby byl přístup k přístupnosti, nikoli internal
public
:
public class Person
{
public string? FirstName { get; private set; }
// Omitted for brevity.
}
FirstName
Vlastnost lze číst z libovolného kódu, ale lze ji přiřadit pouze z kódu ve Person
třídě.
K sadě nebo získání přístupových objektů můžete přidat libovolný modifikátor omezujícího přístupu. Modifikátor přístupu u jednotlivého přístupového objektu musí být více omezující než přístup vlastnosti. Předchozí kód je právní, protože vlastnost FirstName
je public
, ale set příslušenství je private
. Nelze deklarovat private
vlastnost s příslušenstvím public
. Deklarace vlastností lze také deklarovat protected
, internal
, , protected internal
nebo dokonce private
.
Existují dva speciální modifikátory přístupu pro set
přístupové objekty:
- Přístupový
set
objekt může mítinit
jako modifikátor přístupu. Tentoset
přístup lze volat pouze z inicializátoru objektů nebo konstruktorů typu. Je to více omezující nežprivate
u přístupového objektuset
. - Automaticky implementovaná vlastnost může deklarovat
get
příslušenství bez přístupového objektuset
. V takovém případě kompilátor umožňujeset
, aby se přístupové objekty volaly pouze z konstruktorů typu. Je to více omezující nežinit
přístup na přístupovém objektuset
.
Person
Upravte třídu následujícím způsobem:
public class Person
{
public Person(string firstName) => FirstName = firstName;
public string FirstName { get; }
// Omitted for brevity.
}
Předchozí příklad vyžaduje, aby volající používali konstruktor, který obsahuje FirstName
parametr. Volající nemůžou k přiřazení hodnoty vlastnosti použít inicializátory objektů. Chcete-li podporovat inicializátory, můžete příslušenství nastavit set
jako přístup init
, jak je znázorněno v následujícím kódu:
public class Person
{
public Person() { }
public Person(string firstName) => FirstName = firstName;
public string? FirstName { get; init; }
// Omitted for brevity.
}
Tyto modifikátory se často používají s modifikátorem required
k vynucení správné inicializace.
Vlastnosti se záložními poli
Koncept počítané vlastnosti můžete kombinovat s privátním polem a vytvořit vyhodnocenou vlastnost uloženou v mezipaměti. Například aktualizujte FullName
vlastnost tak, aby se formátování řetězců stalo u prvního přístupu:
public class Person
{
public Person() { }
[SetsRequiredMembers]
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public required string FirstName { get; init; }
public required string LastName { get; init; }
private string? _fullName;
public string FullName
{
get
{
if (_fullName is null)
_fullName = $"{FirstName} {LastName}";
return _fullName;
}
}
}
Tato implementace funguje, protože vlastnosti FirstName
jsou LastName
jen pro čtení. Lidé můžou změnit jméno. FirstName
Aktualizace vlastností takLastName
, aby umožňovaly set
přístupové objekty, vyžaduje, abyste zneplatňovali jakoukoli hodnotu uloženou v mezipaměti pro fullName
. set
Upravíte přístupové objekty FirstName
a LastName
vlastnost tak, aby fullName
se pole znovu vypočítalo:
public class Person
{
private string? _firstName;
public string? FirstName
{
get => _firstName;
set
{
_firstName = value;
_fullName = null;
}
}
private string? _lastName;
public string? LastName
{
get => _lastName;
set
{
_lastName = value;
_fullName = null;
}
}
private string? _fullName;
public string FullName
{
get
{
if (_fullName is null)
_fullName = $"{FirstName} {LastName}";
return _fullName;
}
}
}
Tato konečná verze vyhodnocuje FullName
vlastnost pouze v případě potřeby. Dříve počítaná verze se použije, pokud je platná. V opačném případě výpočet aktualizuje hodnotu uloženou v mezipaměti. Vývojáři používající tuto třídu nemusí znát podrobnosti implementace. Žádný z těchto vnitřních změn nemá vliv na použití objektu Person.
Počínaje jazykem C# 13 můžete vytvářet partial
vlastnosti ve partial
třídách. Implementovaná deklarace vlastnosti partial
nemůže být automaticky implementovaná vlastnost. Automaticky implementovaná vlastnost používá stejnou syntaxi jako deklarující částečnou deklaraci vlastnosti.
Vlastnosti
Vlastnosti jsou formou inteligentních polí ve třídě nebo objektu. Zvnějšku objektu se zobrazí jako pole v objektu. Vlastnosti je však možné implementovat pomocí celé palety funkcí jazyka C#. Můžete zadat ověřování, různé přístupnosti, opožděné vyhodnocení nebo jakékoli požadavky, které vaše scénáře potřebují.
- Jednoduché vlastnosti, které nevyžadují žádný vlastní přístupový kód, lze implementovat buď jako definice těla výrazu, nebo jako automaticky implementované vlastnosti.
- Vlastnosti umožňují třídě zveřejnit veřejný způsob získání a nastavení hodnot při skrytí implementace nebo ověřovacího kódu.
- K vrácení hodnoty vlastnosti slouží přístupové objekty get a k přiřazení nové hodnoty se používá objekt pro nastavení vlastnosti. Inicializační objekt vlastnosti se používá k přiřazení nové hodnoty pouze během vytváření objektů. Tyto přístupové objekty můžou mít různé úrovně přístupu. Další informace naleznete v tématu Omezení přístupnosti přístupového objektu.
- Klíčové slovo hodnoty slouží k definování hodnoty, kterou
set
přiřazuje.init
- Vlastnosti můžou být jen pro čtení (mají přístupové
set
get
objekty i přístupové objekty), jen pro čtení (mají přístupovéget
objekty, ale žádnéset
přístupové objekty) nebo jen pro zápis (majíset
přístupové objekty, ale žádnéget
přístupové objekty). Vlastnosti jen pro zápis jsou vzácné.
Specifikace jazyka C#
Další informace naleznete v tématu Vlastnosti ve specifikaci jazyka C#. Specifikace jazyka je úplným a rozhodujícím zdrojem pro syntaxi a použití jazyka C#.