A tulajdonságokhoz való hozzáférés korlátozása
Az osztály meghatározhatja, hogy az egyes tagok milyen módon legyenek elérhetők az osztályon kívüli kódhoz. Az osztályon vagy szerelvényen kívülről nem használható metódusok és változók rejtve lehetnek a kódolási hibák vagy rosszindulatú kihasználások lehetőségének korlátozása érdekében.
Egyes metódusokat és tulajdonságokat egy osztályon kívüli kódból, más néven ügyfélkódból kell meghívni vagy elérni. Más metódusok és tulajdonságok csak az osztályban használhatók. Fontos korlátozni a kód akadálymentességét, hogy csak a kívánt ügyfélkód érhesse el. A következő hozzáférési módosítók használatával adhatja meg, hogy a típusok és a tagok milyen módon legyenek elérhetők az ügyfélkódhoz:
-
public: A típust vagy tagot az ugyanabban a szerelvényben lévő bármely más kód vagy egy rá hivatkozó másik szerelvény is elérheti. -
protected: A típus vagy tag csak kóddal érhető el ugyanabban az osztályban vagy származtatott osztályban. -
internal: A típust vagy tagot ugyanannak a szerelvénynek bármely kódja elérheti, egy másik szerelvényből azonban nem. -
protected internal: A típust vagy tagot egy szerelvény bármely kódja vagy egy másik szerelvény bármely származtatott osztálya elérheti. -
private: A típus vagy tag csak kóddal érhető el ugyanabban az osztályban vagy szerkezetben. -
private protected: A típus vagy tag csak kód alapján érhető el ugyanabban a szerelvényben, és csak az ugyanabban az osztályban vagy származtatott osztályban lévő kód alapján.
Az osztálytagok alapértelmezés szerint private hozzáféréssel vannak hozzárendelve.
A tulajdonságok és tartozékok módosítóinak elérése
A modul ezen pontig a get és set tartozékait tartalmazó tulajdonságokra összpontosítottunk. Ezeket a tulajdonságokat írási-olvasási tulajdonságoknak nevezzük. Az írási-olvasási tulajdonságok mellett írásvédett tulajdonságokat is létrehozhat, vagy különböző kisegítő lehetőségeket biztosíthat a set és get tartozékai számára.
Alapértelmezés szerint get és set tartozékai ugyanolyan kisegítő szinttel rendelkeznek, mint az a tulajdonság, amelyhez tartoznak. Azonban korlátozhatja a get vagy set tartozék elérhetőségét. A hozzáférési módosítók akkor hasznosak, ha korlátozni szeretné a tulajdonsághoz való hozzáférést, de továbbra is engedélyezi a tulajdonság értékéhez való hozzáférést egy get tartozékon keresztül.
Tegyük fel, hogy van egy Person osztálya, amely csak a FirstName tulajdonság értékének módosítását engedélyezi az osztály más metódusaitól. Belső vagy nyilvános helyett privát akadálymentességet biztosíthat a set tartozéknak:
public class Person
{
public string? FirstName { get; private set; }
// Omitted for brevity.
}
A FirstName tulajdonság bármely kódból olvasható, de csak a Person osztály kódjából rendelhető hozzá.
Bármilyen korlátozó hozzáférés-módosító hozzáadható a set vagy get tartozékhoz. Az egyes tartozékokon a hozzáférés-módosítónak szigorúbbnak kell lennie, mint a tulajdonsághoz való hozzáférés. Az előző kód azért jogi, mert a FirstName tulajdonság public, de a set tartozék private. Nem deklarálhat private tulajdonságot public tartozékkal. A tulajdonságdeklarációk protected, internal, protected internalvagy akár privateis deklarálhatók.
A set tartozékaihoz két speciális hozzáférési módosító használható:
- Egy
settartozék hozzáférés-módosítókéntinitis rendelkezhet. Ez asettartozék csak egy objektum inicializálójától vagy a típus konstruktoraitól hívható meg. Szigorúbb, mint aprivatetartozékset. - Az automatikusan implementált tulajdonság
gettartozék nélkül deklarálhatsettartozékot. Ebben az esetben a fordító lehetővé teszi, hogy asettartozék csak a típus konstruktoraiból legyen meghívva. Szigorúbb, mint ainittartozéksettartozéka.
Fontolja meg a Person osztály következő frissítéseit:
public class Person
{
public Person(string firstName) => FirstName = firstName;
public string FirstName { get; }
// Omitted for brevity.
}
Az előző példában a hívóknak a FirstName paramétert tartalmazó konstruktort kell használniuk. A hívók nem használhatnak objektum inicializálókat, hogy értéket rendeljenek a tulajdonsághoz. Az inicializálók támogatásához a set tartozékot init kiegészítővé teheti, ahogyan az alábbi kódban látható:
public class Person
{
public Person() { }
public Person(string firstName) => FirstName = firstName;
public string? FirstName { get; init; }
// Omitted for brevity.
}
Ezeket a módosítókat gyakran használják a required módosítóval a megfelelő inicializálás kényszerítéséhez.
A tartozék akadálymentességének korlátozása
Bizonyos esetekben hasznos lehet korlátozni a get vagy set tartozékhoz való hozzáférést. Általában korlátozza a set tartozék akadálymentességét, miközben a get tartozék nyilvánosan elérhető marad.
Például:
private string _name = "Hello";
public string Name
{
get
{
return _name;
}
protected set
{
_name = value;
}
}
Ebben a példában egy Name nevű tulajdonság definiál egy get és set tartozékot. A get tartozék maga a tulajdonság akadálymentességi szintjét kapja, public ebben az esetben, míg a set tartozék kifejezetten korlátozott, ha a protected hozzáférési módosítóját alkalmazza magára a tartozékra.
A tartozékokkal kapcsolatos hozzáférési módosítók korlátozásai
A tartozékmódosítók tulajdonságokon vagy indexelőkön való használatára a következő feltételek vonatkoznak:
- A kiegészítő módosítókat csak akkor használhatja, ha a tulajdonság
setésgettartozékokkal is rendelkezik. Ebben az esetben a módosító csak a két tartozék egyikén engedélyezett. - A tartozék akadálymentességi szintjének szigorúbbnak kell lennie, mint magának a tulajdonságnak vagy indexelőnek az akadálymentességi szintje.
Írásvédett statikus tulajdonságok
Az alábbi példa a példány és a statikus tulajdonságok osztályban való használatát mutatja be.
A Employee osztálynak van egy Counter nevű statikus tulajdonsága, amely nyomon követi a létrehozott osztálypéldányok számát. A Counter tulajdonság írásvédett, ami azt jelenti, hogy az osztályon kívülről is elérhető, de nem módosítható. A Counter tulajdonság is static, ami azt jelenti, hogy a Counter értéket az Employee osztály használatával éri el, nem az osztály employee1 vagy employee2 példányaival.
public class Employee
{
public static int NumberOfEmployees;
private static int _counter;
private string _name;
// A read-write instance property:
public string Name
{
get => _name;
set => _name = value;
}
// A read-only static property:
public static int Counter => _counter;
// A Constructor:
public Employee() => _counter = ++NumberOfEmployees; // Calculate the employee's number:
}
public class Program
{
static void Main(string[] args)
{
// Create an initial instance of the Employee class
Employee employee1 = new Employee { Name = "NameOne" };
// Display the name and counter values
Console.WriteLine($"Employee 1: Name = {employee1.Name}, Counter = {Employee.Counter}");
// Create a second instance of the Employee class
Employee employee2 = new Employee { Name = "NameTwo" };
// Display the name and counter values
Console.WriteLine($"Employee 2: Name = {employee2.Name}, Counter = {Employee.Counter}");
employee2.Name = "NameThree";
// Display the name and counter values
Console.WriteLine($"Employee 2: Name = {employee2.Name}, Counter = {Employee.Counter}");
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
A Employee osztály a következő tagokat tartalmazza:
-
NumberOfEmployees: Nyilvános statikus mező, amely nyomon követi a létrehozott alkalmazotti példányok teljes számát. Mivel statikus, az Alkalmazott osztály összes példánya között meg van osztva. -
_counter: Egy privát statikus mező, amely egyedi számot rendel minden alkalmazotti példányhoz. Az összes példány között is meg van osztva. -
_name: Az alkalmazott nevét tároló privát példány mező. Ez az Alkalmazott osztály minden egyes példányára vonatkozik. -
Name: Nyilvános írásvédett példánytulajdonság, amely hozzáférést biztosít a _name mezőhöz. Agettartozék visszaadja a_nameértékét , és asettartozék új értéket rendel_name. -
Counter: Nyilvános írásvédett statikus tulajdonság, amely hozzáférést biztosít a_countermezőhöz. Agettartozék a_counterértékét adja vissza. ACountertulajdonság az objektum helyett az osztályhoz van társítva, mert statikus tulajdonságként van definiálva.
A két statikus mező inicializálódik, amikor az osztály először betöltődik a memóriába, mielőtt az osztály bármely példánya létrejön. A C#-ban a statikus mezők inicializálása az alapértelmezett értékükre történik, ha nincs explicit inicializálva.
int mezők esetében az alapértelmezett érték 0.
A statikus tulajdonságok és mezők magukhoz az osztályhoz tartoznak, nem pedig az osztály egy adott példányához. Az osztály minden példánya ugyanazokkal a statikus tulajdonságokkal és mezőkkel rendelkezik.
A konstruktor 1-gyel növeli a NumberOfEmployees statikus mezőt, és hozzárendeli az új értéket a _counter statikus mezőhöz. Ez a módszer biztosítja, hogy minden Employee példány egyedi számot kapjon.
Privát tartozékok
Vegye figyelembe az olvasási-írási tulajdonságokat megvalósító alábbi kódot:
class Person
{
private string _name = "N/A";
private int _age = 0;
// Declare a Name property of type string:
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
// Declare an Age property of type int:
public int Age
{
get
{
return _age;
}
set
{
_age = value;
}
}
}
class TestPerson
{
static void Main()
{
// Create a new Person object:
Person person = new Person();
// Print out the name and the age associated with the person:
Console.WriteLine($"Person details - Name = {person.Name}, Age = {person.Age}");
// Set some values on the person object:
person.Name = "NameOne";
person.Age = 99;
Console.WriteLine($"Person details - Name = {person.Name}, Age = {person.Age}");
// Increment the Age property:
person.Age += 1;
Console.WriteLine($"Person details - Name = {person.Name}, Age = {person.Age}");
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output:
Person details - Name = N/A, Age = 0
Person details - Name = NameOne, Age = 99
Person details - Name = NameOne, Age = 100
*/
Ebben a példában a Person osztály Name és Age tulajdonságokat tartalmaz. A tulajdonságok nyilvánosak, és get és set tartozékokat is tartalmaznak. A nyilvános tartozékokkal bármely objektum elolvashatja és megírhatja ezeket a tulajdonságokat.
Néha ki kell zárni az egyik tartozékot. Kihagyhatja a set tartozékot, hogy a tulajdonság írásvédett legyen:
public string Name
{
get
{
return _name;
}
}
Másik lehetőségként közzéteheti az egyik tartozékot nyilvánosan, de a másikat magánjellegűvé vagy védetté teheti.
public string Name
{
get
{
return _name;
}
private set
{
_name = value;
}
}