Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Az osztály- vagy szerkezetdefiníció olyan, mint egy terv, amely meghatározza, hogy mit tehet a típus. Az objektum alapvetően egy memóriablokk, amely a terv szerint lett lefoglalva és konfigurálva. Egy program több objektumot is létrehozhat ugyanahhoz az osztályhoz. Az objektumokat példányoknak is nevezik, és elnevezett változókban, tömbökben vagy gyűjteményekben tárolhatók. Az ügyfélkód az a kód, amely ezeket a változókat használja a metódusok meghívására és az objektum nyilvános tulajdonságainak elérésére. Egy objektumorientált nyelvben, például a C#-ban egy tipikus program több, dinamikusan kommunikáló objektumból áll.
Megjegyzés
A statikus típusok másképp viselkednek, mint az itt leírtak. További információ: Statikus osztályok és statikus osztálytagok.
Struktúrapéldányok és osztálypéldányok
Mivel az osztályok referenciatípusok, az osztályobjektumok változói a felügyelt halom objektumának címére mutató hivatkozást tárolnak. Ha az első változóhoz egy azonos típusú második változó van hozzárendelve, akkor mindkét változó az adott címen található objektumra hivatkozik. Ezt a pontot a cikk későbbi részében részletesebben tárgyaljuk.
Az osztályok példányai a new
operátorhasználatával jönnek létre. Az alábbi példában Person
a típus, a person1
és a person2
pedig az adott típusú példányok vagy objektumok.
using System;
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person(string name, int age)
{
Name = name;
Age = age;
}
// Other properties, methods, events...
}
class Program
{
static void Main()
{
Person person1 = new Person("Leopold", 6);
Console.WriteLine($"person1 Name = {person1.Name} Age = {person1.Age}");
// Declare new person, assign person1 to it.
Person person2 = person1;
// Change the name of person2, and person1 also changes.
person2.Name = "Molly";
person2.Age = 16;
Console.WriteLine($"person2 Name = {person2.Name} Age = {person2.Age}");
Console.WriteLine($"person1 Name = {person1.Name} Age = {person1.Age}");
}
}
/*
Output:
person1 Name = Leopold Age = 6
person2 Name = Molly Age = 16
person1 Name = Molly Age = 16
*/
Mivel a szerkezetek értéktípusok, egy struct objektum változója a teljes objektum másolatát tartalmazza. A szerkezetpéldányok a new
operátorral is létrehozhatók, de ez nem kötelező, ahogy az alábbi példában látható:
using System;
namespace Example
{
public struct Person
{
public string Name;
public int Age;
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
public class Application
{
static void Main()
{
// Create struct instance and initialize by using "new".
// Memory is allocated on thread stack.
Person p1 = new Person("Alex", 9);
Console.WriteLine($"p1 Name = {p1.Name} Age = {p1.Age}");
// Create new struct object. Note that struct can be initialized
// without using "new".
Person p2 = p1;
// Assign values to p2 members.
p2.Name = "Spencer";
p2.Age = 7;
Console.WriteLine($"p2 Name = {p2.Name} Age = {p2.Age}");
// p1 values remain unchanged because p2 is copy.
Console.WriteLine($"p1 Name = {p1.Name} Age = {p1.Age}");
}
}
/*
Output:
p1 Name = Alex Age = 9
p2 Name = Spencer Age = 7
p1 Name = Alex Age = 9
*/
}
A p1
és a p2
memóriája a szálveremen le van foglalva. A memória visszanyerése a deklarált típussal vagy módszerrel együtt történik. Ez az egyik oka annak, hogy a struktúrák másolódnak hozzárendeléskor. Ezzel szemben az osztálypéldányhoz lefoglalt memóriát a közös nyelvi futtatókörnyezet automatikusan visszanyeri (szemétgyűjtés), amikor az objektumra mutató összes hivatkozás kifogyott a hatókörből. Nem lehet determinisztikus módon megsemmisíteni egy osztályobjektumot, mint a C++-ban. A .NET-beli szemétgyűjtésről további információt a Szemétgyűjtéscímű témakörben talál.
Megjegyzés
A memória lefoglalása és felszabadítása a felügyelt halomon nagy mértékben optimalizálva van a közös nyelvi futtatókörnyezetben. A legtöbb esetben nincs jelentős különbség az osztálypéldányok halomra történő kiosztásának és a struktúrapéldányok verembe történő kiosztásának teljesítményköltségében.
Objektumdentitás és értékegyenlőség
Ha összehasonlít két objektumot az egyenlőség érdekében, először meg kell különböztetnie, hogy tudni szeretné, hogy a két változó ugyanazt az objektumot jelöli-e a memóriában, vagy egy vagy több mező értéke egyenértékű-e. Ha értékeket szeretne összehasonlítani, mérlegelnie kell, hogy az objektumok értéktípusok (szerkezetek) vagy referenciatípusok (osztályok, meghatalmazottak, tömbök) példányai-e.
Annak megállapításához, hogy két osztálypéldány ugyanarra a helyre hivatkozik-e a memóriában (ami azt jelenti, hogy azonos identitással), használja a statikus Object.Equals metódust. (System.Object az összes értéktípus és referenciatípus implicit alaposztálya, beleértve a felhasználó által definiált szerkezeteket és osztályokat.)
Annak megállapításához, hogy a két strukturált példány példánymezői azonos értékekkel rendelkeznek-e, használja a ValueType.Equals metódust. Mivel minden struktúra implicit módon a System.ValueType-től örököl, a metódust közvetlenül az objektumán hívhatja meg, ahogy az alábbi példában látható.
// Person is defined in the previous example. //public struct Person //{ // public string Name; // public int Age; // public Person(string name, int age) // { // Name = name; // Age = age; // } //} Person p1 = new Person("Wallace", 75); Person p2 = new Person("", 42); p2.Name = "Wallace"; p2.Age = 75; if (p2.Equals(p1)) Console.WriteLine("p2 and p1 have the same values."); // Output: p2 and p1 have the same values.
A System.ValueType megvalósítása a
Equals
-ben bizonyos esetekben dobozolást és reflexiót használ. A típusra jellemző hatékony egyenlőségi algoritmus biztosításáról további információt Az értékegyenlőség meghatározásacímű témakörben talál. A rekordok olyan referenciatípusok, amelyek értékszemantikát használnak az egyenlőséghez.Annak megállapításához, hogy a két osztálypéldány mezői egyenlők-e, használhatja a Equals metódust vagy a == operátort. Azonban csak akkor használja őket, ha az osztály felülbírálta vagy túlterhelte őket, hogy egyéni definíciót adjon arról, hogy mit jelent az "egyenlőség" az ilyen típusú objektumok esetében. Az osztály a IEquatable<T> felületet vagy a IEqualityComparer<T> felületet is implementálhatja. Mindkét interfész olyan módszereket biztosít, amelyekkel tesztelhető az értékegyenlőség. Amikor saját osztályokat tervez, amelyek felülbírálják a
Equals
-t, feltétlenül kövesse az irányelveket, amelyeket az Értékegyenlőség meghatározása egy típushoz és Object.Equals(Object)című dokumentumban ismertetnek.
Kapcsolódó szakaszok
További információ: