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 egy memóriablokk, amelyet a program a terv szerint foglal le és konfigurál. Egy program több objektumot is létrehozhat ugyanahhoz az osztályhoz. Az objektumokat példányoknak is nevezhetjük. Ezeket egy elnevezett változóban, tömbben vagy gyűjteményben tárolhatja. Az ügyfélkód ezen változók használatával hívja meg a metódusokat, és hozzáfér az objektum nyilvános tulajdonságaihoz. 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 a cikkben leírtak. További információ: Statikus osztályok és statikus osztálytagok.
Struktúrák példányai és osztályok példányai
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 egy második, azonos típusú változót rendel az első változóhoz, mindkét változó az adott címen található objektumra hivatkozik. Ez a cikk később részletesebben ismerteti ezt a pontot.
Az operátorralnew osztálypéldányokat hozhat 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(string name, int age)
{
public string Name { get; set; } = name;
public int Age { get; set; } = age;
// Other properties, methods, events...
}
class Program
{
static void Main()
{
Person person1 = new("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 struktúrapéldányokat az new operátorral is létrehozhatja, de nem kell használnia, 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("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 szálverem memóriát foglal le mind a p1, mind a p2 számára. A program visszanyeri ezt a memóriát a deklarált típussal vagy módszerrel együtt. Ez a memóriakezelés az egyik oka annak, hogy a struktúrák értékadáskor másolódnak. Ezzel szemben a Common Language Runtime automatikusan felszabadítja (szemétgyűjtéssel) az egy osztálypéldány számára lefoglalt memóriát, amikor az objektumra mutató összes hivatkozás kikerül 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 közös nyelvi futtatókörnyezet nagymértékben optimalizálja a memória lefoglalását és felszabadítását a felügyelt halomra. A legtöbb esetben nincs jelentős különbség az osztálypéldányok kiosztásának a halomra történő teljesítményköltségében, szemben egy struktúra példányának a veremre való kiosztásával.
Objektumdentitás és értékegyenlőség
Ha két objektumot hasonlít össze az egyenlőség érdekében, először döntse el, hogy szeretné-e tudni, 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ű. Ha össze szeretné hasonlítani az értékeket, fontolja meg, hogy az objektumok értéktípusok (szerkezetek) vagy referenciatípusok (osztályok, meghatalmazottak, tömbök) példányai-e.
A statikus Object.ReferenceEquals módszerrel állapítsa meg, hogy két osztálypéldány ugyanarra a helyre hivatkozik-e a memóriában (ami azt jelenti, hogy azonos identitással rendelkeznek). (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.)
Alapértelmezés szerint a ValueType.Equals metódus határozza meg, hogy a két strukturált példány példánymezői azonos értékekkel rendelkeznek-e. 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(string name, int age) //{ // public string Name { get; set; } = name; // public int Age { get; set; } = age; //} Person p1 = new("Wallace", 75); Person p2 = new("", 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.Az alapértelmezett System.ValueType implementáció
Equalsbizonyos esetekben alkalmazza az érték-dobozolást és a reflexiót. Az Ön típusára jellemző hatékony egyenlőségi algoritmus biztosításáról az Egyenlőség megvalósítása saját maga című témakörben olvashat, ha egy típus nem lehet rekord. 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. Azoknak a saját osztályoknak a tervezésekor, amelyek felülírják a
Equalsmetódust, ügyeljen arra, hogy kövesse a Az egyenlőség megvalósítása saját kezűleg, ha egy típus nem lehet rekordtípus és a Object.Equals(Object) témakörben ismertetett irányelveket.
Kapcsolódó szakaszok
További információkért lásd: