Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
En egenskap är en medlem som tillhandahåller en flexibel mekanism för att läsa, skriva eller beräkna värdet för ett datafält. Egenskaper visas som medlemmar i offentliga data, men de implementeras som särskilda metoder som kallas accessorer. Den här funktionen gör det möjligt för anropare att enkelt komma åt data och bidrar fortfarande till att främja datasäkerhet och flexibilitet. Syntaxen för egenskaper är ett naturligt tillägg till fält. Ett fält definierar en lagringsplats:
public class Person
{
public string? FirstName;
// Omitted for brevity.
}
Automatiskt implementerade egenskaper
En egenskapsdefinition innehåller deklarationer för en get-accessor och en set-accessor som hämtar och tilldelar värdet för den egenskapen.
public class Person
{
public string? FirstName { get; set; }
// Omitted for brevity.
}
Föregående exempel visar en automatiskt implementerad egenskap. Kompilatorn genererar ett dolt stödfält för egenskapen. Kompilatorn implementerar också brödtexten för get och set -accessorerna. Alla attribut tillämpas på den automatiskt implementerade egenskapen. Du kan använda attributet för det kompilatorgenererade bakgrundsfältet genom att ange taggen field: för attributet.
Du kan initiera en egenskap till ett annat värde än standardvärdet genom att ange ett värde efter den avslutande klammerparentesen för egenskapen. Du kanske föredrar att det ursprungliga värdet för egenskapen är den tomma strängen i stället FirstNameför null . Du anger det enligt följande kod:
public class Person
{
public string FirstName { get; set; } = string.Empty;
// Omitted for brevity.
}
Fältstödda egenskaper
I C# 14 kan du lägga till validering eller annan logik i accessorn för en egenskap med hjälp av nyckelordet field . Nyckelordet field kommer åt kompilatorns syntetiserade bakgrundsfält för en egenskap. Det gör att du kan skriva en egenskapsaccessor utan att uttryckligen deklarera ett separat underliggande fält.
public class Person
{
public string? FirstName
{
get;
set => field = value.Trim();
}
// Omitted for brevity.
}
Nödvändiga egenskaper
I föregående exempel kan en anropare skapa en Person med hjälp av standardkonstruktorn, utan att FirstName ange egenskapen. Egenskapen ändrade typen till en nullbar sträng. Du kan kräva att anropare anger en egenskap:
public class Person
{
public Person() { }
[SetsRequiredMembers]
public Person(string firstName) => FirstName = firstName;
public required string FirstName { get; init; }
// Omitted for brevity.
}
Föregående kod gör två ändringar i Person klassen. Först innehåller egenskapsdeklarationen FirstNamerequired modifieraren. Det innebär att all kod som skapar en ny Person måste ange den här egenskapen med hjälp av en objektinitierare. För det andra har konstruktorn som tar en firstName parameter attributet System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute . Det här attributet informerar kompilatorn om att konstruktorn anger allarequired medlemmar. Anropare som använder den här konstruktorn behöver inte ange required egenskaper med en objektinitierare.
Viktigt!
Blanda inte ihop required med "non-nullable". Det är giltigt att ange en required egenskap till null eller default. Om typen inte är nullbar, till exempel string i de här exemplen, utfärdar kompilatorn en varning.
var aPerson = new Person("John");
aPerson = new Person { FirstName = "John"};
// Error CS9035: Required member `Person.FirstName` must be set:
//aPerson2 = new Person();
Definitioner av uttrycksblock
Egenskapsåtkomster består ofta av enrads-instruktioner. Accessorerna tilldelar eller returnerar resultatet av ett uttryck. Du kan implementera dessa egenskaper som uttrycksbaserade medlemmar. Uttryckstextdefinitioner består av => token följt av uttrycket som ska tilldelas till eller hämtas från egenskapen.
Skrivskyddade egenskaper kan implementera get accessorn som en uttrycksbaserad medlem. I följande exempel implementeras den skrivskyddade Name egenskapen som en uttrycksbaserad medlem:
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.
}
Egenskapen Name är en beräknad egenskap. Det finns inget bakgrundsfält för Name. Egenskapen beräknar den varje gång.
Åtkomstkontroll
Föregående exempel visade läs-/skrivegenskaper. Du kan också skapa endast läsbara egenskaper, eller ge olika åtkomstnivåer till set- och get-accessorerna. Anta att klassen Person endast ska aktivera ändring av värdet för FirstName egenskapen från andra metoder i klassen. Du kan ge set-tillträdessättaren private tillgänglighet i stället för internal eller public:
public class Person
{
public string? FirstName { get; private set; }
// Omitted for brevity.
}
Egenskapen FirstName kan läsas från valfri kod, men den kan endast tilldelas från kod i Person klassen.
Du kan lägga till vilken som helst restriktiv åtkomstmodifierare för antingen set- eller get-accessorer. En åtkomstmodifierare för en enskild accessor måste vara mer restriktiv än åtkomsten till egenskapen. Föregående kod är laglig eftersom egenskapen FirstName är public, men den angivna accessorn är private. Det gick inte att deklarera en private egenskap med en public accessor. Egenskapsdeklarationer kan också deklareras protected, internal, protected internaleller till och med private.
Det finns två särskilda åtkomstmodifierare för set accessorer:
- En
setaccessor kan hainitsom åtkomstmodifierare. Accessornsetkan endast anropas från en objektinitialiserare eller typens konstruktorer. Det är mer restriktivt änprivatepåsetaccessorn. - En automatiskt implementerad egenskap kan deklarera en
getaccessor utan ensetaccessor. I så fall tillåter kompilatorn att accessorn endast anropas från typens konstruktorer. Det är mer restriktivt äninit-accessorn påset-accessorn.
Person Ändra klassen så här:
public class Person
{
public Person(string firstName) => FirstName = firstName;
public string FirstName { get; }
// Omitted for brevity.
}
Föregående exempel kräver att anropare använder konstruktorn som innehåller parametern FirstName . Anropare kan inte använda objektinitierare för att tilldela egenskapen ett värde. Om du vill stödja initialiserare kan du göra set accessorn till en init accessor, som du ser i följande kod:
public class Person
{
public Person() { }
public Person(string firstName) => FirstName = firstName;
public string? FirstName { get; init; }
// Omitted for brevity.
}
Dessa modifierare används ofta med required modifieraren för att framtvinga korrekt initiering.
Egenskaper med bakgrundsfält
Du kan kombinera idén om en beräknad egenskap med ett privat fält och skapa en cachelagrad utvärderad egenskap. Uppdatera till exempel FullName egenskapen så att strängformateringen sker vid den första åtkomsten:
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;
}
}
}
Den här implementeringen fungerar eftersom egenskaperna FirstName och LastName är skrivskyddade. Folk kan ändra sitt namn. Om du uppdaterar FirstName- och LastName-egenskaperna för att tillåta set-åtkomst måste du ogiltigförklara alla cachelagrade värden för fullName. Du ändrar set-accessorerna för FirstName- och LastName-egenskaperna så att fullName-fältet beräknas igen.
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;
}
}
}
Den här slutliga versionen utvärderar FullName egenskapen endast när det behövs. Den tidigare beräknade versionen används om den är giltig. Annars uppdaterar beräkningen det cachelagrade värdet. Utvecklare som använder den här klassen behöver inte känna till informationen om implementeringen. Ingen av dessa interna ändringar påverkar användningen av personobjektet.
Från och med C# 13 kan du skapa partial egenskaper i partial klasser. Implementeringsdeklarationen för en partial egenskap kan inte vara en automatiskt implementerad egenskap. En automatiskt implementerad egenskap använder samma syntax som en deklaration av en partiell egenskap.
Egenskaper
Egenskaper är en form av smarta fält i en klass eller ett objekt. Utanför objektet visas de som fält i objektet. Egenskaper kan dock implementeras med hjälp av den fullständiga paletten med C#-funktioner. Du kan tillhandahålla validering, olika tillgänglighetsalternativ, lat utvärdering eller alla krav som dina scenarier behöver.
- Enkla egenskaper som inte kräver någon anpassad åtkomstkod kan implementeras antingen som uttryckstextdefinitioner eller som automatiskt implementerade egenskaper.
- Med egenskaper kan en klass exponera ett offentligt sätt att hämta och ange värden, samtidigt som implementerings- eller verifieringskoden döljs.
- En get-egenskapsåtkomst används för att returnera egenskapsvärdet och en set-egenskapsåtkomst används för att tilldela ett nytt värde. En init-egenskapstillgång används endast för att tilldela ett nytt värde under själva objektets konstruktion. Dessa accessorer kan ha olika åtkomstnivåer. För mer information, se Begränsa tillgängligheten av accessorer.
- Nyckelordet värde används för att definiera det värde som
set- ellerinit-accessorn tilldelar. - Egenskaper kan vara skrivskyddade (de har både en
getoch ensetaccessor), skrivskyddade (de har engetaccessor men ingensetaccessor) eller skrivskyddade (de har ensetaccessor, men ingengetaccessor). Egenskaper som bara kan skrivas till är sällsynta.
Språkspecifikation för C#
Mer information finns i Egenskaper i C#-språkspecifikationen. Språkspecifikationen är den slutgiltiga källan för C#-syntax och -användning.