Objekty – vytváření instancí typů
Definice třídy nebo struktury je jako podrobný plán, který určuje, co může typ dělat. Objekt je v podstatě blok paměti, který byl přidělen a nakonfigurován podle podrobného plánu. Program může vytvořit mnoho objektů stejné třídy. Objekty se také nazývají instance a mohou být uloženy buď v pojmenované proměnné, nebo v poli nebo kolekci. Kód klienta je kód, který tyto proměnné používá k volání metod a přístup k veřejným vlastnostem objektu. V objektově orientovaném jazyce, jako je C#, se typický program skládá z více objektů, které interagují dynamicky.
Poznámka:
Statické typy se chovají jinak než zde popsané. Další informace naleznete v tématu Statické třídy a členy statické třídy.
Instance struktury vs. instance tříd
Vzhledem k tomu, že třídy jsou odkazové typy, proměnná objektu třídy obsahuje odkaz na adresu objektu ve spravované haldě. Pokud je k první proměnné přiřazena druhá proměnná stejného typu, obě proměnné odkazují na objekt na této adrese. Tento bod je podrobněji popsán dále v tomto článku.
Instance tříd se vytvářejí pomocí operátorunew
. V následujícím příkladu Person
je typ a person1
person2
jsou instancemi nebo objekty tohoto typu.
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 = {0} Age = {1}", person1.Name, 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 = {0} Age = {1}", person2.Name, person2.Age);
Console.WriteLine("person1 Name = {0} Age = {1}", person1.Name, person1.Age);
}
}
/*
Output:
person1 Name = Leopold Age = 6
person2 Name = Molly Age = 16
person1 Name = Molly Age = 16
*/
Vzhledem k tomu, že struktury jsou typy hodnot, proměnná objektu struktury obsahuje kopii celého objektu. Instance struktur lze také vytvořit pomocí operátoru new
, ale to není povinné, jak je znázorněno v následujícím příkladu:
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 = {0} Age = {1}", p1.Name, 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 = {0} Age = {1}", p2.Name, p2.Age);
// p1 values remain unchanged because p2 is copy.
Console.WriteLine("p1 Name = {0} Age = {1}", p1.Name, p1.Age);
}
}
/*
Output:
p1 Name = Alex Age = 9
p2 Name = Spencer Age = 7
p1 Name = Alex Age = 9
*/
}
Paměť pro obě p1
a p2
je přidělena v zásobníku vláken. Tato paměť je uvolněna spolu s typem nebo metodou, ve které je deklarována. To je jeden z důvodů, proč se struktury kopírují při přiřazení. Naproti tomu paměť přidělená pro instanci třídy je automaticky uvolněna (uvolňování paměti) modulem CLR (Common Language Runtime), když všechny odkazy na objekt zmizely z oboru. Není možné deterministicky zničit objekt třídy, jako je v jazyce C++. Další informace o uvolňování paměti v .NET naleznete v tématu Uvolňování paměti.
Poznámka:
Přidělení a uvolnění paměti ve spravované haldě je vysoce optimalizované v modulu CLR (Common Language Runtime). Ve většině případů není žádný významný rozdíl v nákladech na výkon přidělení instance třídy na haldě a přidělení instance struktury v zásobníku.
Identita objektu versus rovnost hodnot
Při porovnávání dvou objektů pro rovnost je třeba nejprve rozlišit, zda chcete zjistit, zda tyto dvě proměnné představují stejný objekt v paměti, nebo zda jsou hodnoty jednoho nebo více polí ekvivalentní. Pokud máte v úmyslu porovnávat hodnoty, musíte zvážit, jestli jsou objekty instancemi typů hodnot (struktury) nebo odkazovými typy (třídy, delegáty, matice).
Chcete-li zjistit, zda dvě instance třídy odkazují na stejné umístění v paměti (což znamená, že mají stejnou identitu), použijte statickou Object.Equals metodu. (System.Object je implicitní základní třída pro všechny typy hodnot a odkazové typy, včetně uživatelem definovaných struktur a tříd.)
Chcete-li zjistit, zda pole instance ve dvou instancích struktury mají stejné hodnoty, použijte metodu ValueType.Equals . Vzhledem k tomu, že všechny struktury implicitně dědí z System.ValueType, voláte metodu přímo na objektu, jak je znázorněno v následujícím příkladu:
// 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.
Implementace System.ValueType
Equals
použití boxingu a reflexe v některých případech. Informace o tom, jak poskytnout efektivní algoritmus rovnosti, který je specifický pro váš typ, najdete v tématu Definování rovnosti hodnot pro typ. Záznamy jsou odkazové typy, které pro rovnost používají sémantiku hodnot.Chcete-li zjistit, zda jsou hodnoty polí ve dvou instancích třídy stejné, můžete být schopni použít metodu Equalsnebo operátor == . Použijte je však pouze v případě, že třída přepsala nebo přetížila, aby poskytla vlastní definici toho, co "rovnost" znamená pro objekty tohoto typu. Třída může také implementovat IEquatable<T> rozhraní nebo IEqualityComparer<T> rozhraní. Obě rozhraní poskytují metody, které lze použít k otestování rovnosti hodnot. Při navrhování vlastních tříd, které přepisují
Equals
, nezapomeňte postupovat podle pokynů uvedených v tématu Jak definovat rovnost hodnot pro typ a Object.Equals(Object).
Související oddíly
Další informace: