Anteckning
Å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 klass- eller structdefinition är som en skiss som anger vad typen kan göra. Ett objekt är i princip ett minnesblock som har allokerats och konfigurerats enligt skissen. Ett program kan skapa många objekt i samma klass. Objekt kallas också instanser och kan lagras i antingen en namngiven variabel eller i en matris eller samling. Klientkod är den kod som använder dessa variabler för att anropa metoderna och få åtkomst till objektets offentliga egenskaper. I ett objektorienterat språk, till exempel C#, består ett typiskt program av flera objekt som interagerar dynamiskt.
Anmärkning
Statiska typer fungerar annorlunda än vad som beskrivs här. Mer information finns i Statiska klasser och Statiska klassmedlemmar.
Struct-instanser jämfört med klassinstanser
Eftersom klasser är referenstyper innehåller en variabel för ett klassobjekt en referens till objektets adress på den hanterade heapen. Om en andra variabel av samma typ tilldelas till den första variabeln refererar båda variablerna till objektet på den adressen. Den här punkten beskrivs mer detaljerat senare i den här artikeln.
Instanser av klasser skapas med hjälp av operatornnew
. I följande exempel Person
är typen och person1
och person2
är instanser eller objekt av den typen.
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
*/
Eftersom structs är värdetyper innehåller en variabel för ett struct-objekt en kopia av hela objektet. Instanser av structs kan också skapas med hjälp av operatorn new
, men detta krävs inte, vilket visas i följande exempel:
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
*/
}
Minnet för båda p1
och p2
allokeras i trådstacken. Det minnet frigörs tillsammans med den typ eller metod som det deklareras i. Det här är en anledning till varför structs kopieras vid tilldelning. Däremot frigörs det minne som allokeras för en klassinstans automatiskt (skräpsamlas) av Common Language Runtime när alla referenser till objektet har gått utanför omfånget. Det går inte att deterministiskt förstöra ett klassobjekt som du kan i C++. Mer information om skräpinsamling i .NET finns i Skräpinsamling.
Anmärkning
Allokering och frigöring av minne på den hanterade heap är mycket optimerad för Common Language Runtime. I de flesta fall finns det ingen betydande skillnad i prestandakostnaden för att allokera en klassinstans på heapen jämfört med att allokera en struct-instans på stacken.
Objektidentitet jämfört med värdejämlikhet
När du jämför två objekt för likhet måste du först skilja på om du vill veta om de två variablerna representerar samma objekt i minnet eller om värdena för ett eller flera av deras fält är likvärdiga. Om du tänker jämföra värden måste du överväga om objekten är instanser av värdetyper (structs) eller referenstyper (klasser, ombud, matriser).
Om du vill avgöra om två klassinstanser refererar till samma plats i minnet (vilket innebär att de har samma identitet) använder du den statiska Object.Equals metoden. (System.Object är den implicita basklassen för alla värdetyper och referenstyper, inklusive användardefinierade structs och klasser.)
Använd metoden för att avgöra om instansfälten i två struct-instanser har samma värden ValueType.Equals . Eftersom alla structs implicit ärver från System.ValueTypeanropar du metoden direkt på objektet enligt följande exempel:
// 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.
Genomförandet System.ValueType av
Equals
använder boxning och reflektion i vissa fall. Information om hur du tillhandahåller en effektiv likhetsalgoritm som är specifik för din typ finns i Definiera värdejämlikhet för en typ. Poster är referenstyper som använder värdesemantik för jämställdhet.För att avgöra om värdena för fälten i två klassinstanser är lika med kan du kanske använda Equals metoden eller operatorn == . Använd dem dock bara om klassen har åsidosatt eller överbelastat dem för att ge en anpassad definition av vad "likhet" innebär för objekt av den typen. Klassen kan också implementera IEquatable<T> gränssnittet eller IEqualityComparer<T> gränssnittet. Båda gränssnitten innehåller metoder som kan användas för att testa värdejämlikhet. När du utformar dina egna klasser som åsidosätter
Equals
ska du följa riktlinjerna som anges i Definiera värdejämlikhet för en typ och Object.Equals(Object).
Relaterade avsnitt
Mer information finns i: