Kommentar
Å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 ett minnesblock som programmet allokerar och konfigurerar enligt skissen. Ett program kan skapa många objekt i samma klass. Du kan också anropa objektinstanser. Du kan lagra dem i en namngiven variabel eller i en matris eller samling. Klientkoden 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 i den här artikeln. 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 du tilldelar en andra variabel av samma typ till den första variabeln refererar båda variablerna till objektet på den adressen. I den här artikeln beskrivs den här punkten mer detaljerat senare.
Du skapar instanser av klasser 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(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
*/
}
}
Eftersom structs är värdetyper innehåller en variabel för ett struct-objekt en kopia av hela objektet. Du kan också skapa instanser av structs med hjälp av operatorn new , men du behöver inte använda den, som du ser 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("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
*/
}
Trådstacken allokerar minne för både p1 och p2. Programmet återtar minnet tillsammans med den typ eller metod som du deklarerar det i. Den här minneshanteringen är en av anledningarna till att structs kopieras vid tilldelning. Däremot frigör Common Language Runtime (CLR) automatiskt det minne som allokeras för en instans av en klass när alla referenser till objektet går ur räckvidd (sopinsamlas). Du kan inte deterministiskt förstöra ett klassobjekt som du kan i C++. Mer information om skräpinsamling i .NET finns i Skräpinsamling.
Anmärkning
Common Language Runtime optimerar i hög grad tilldelning och frigöring av minne på den hanterade heapen. 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 avgör du först 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 vill jämföra värden bör du överväga om objekten är instanser av värdetyper (structs) eller referenstyper (klasser, ombud, matriser).
Använd den statiska Object.ReferenceEquals metoden för att avgöra om två klassinstanser refererar till samma plats i minnet (vilket innebär att de har samma identitet). (System.Object är den implicita basklassen för alla värdetyper och referenstyper, inklusive användardefinierade structs och klasser.)
Som standard ValueType.Equals avgör metoden om instansfälten i två struct-instanser har samma värden. 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(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.Standardimplementeringen System.ValueType av
Equalsanvänder boxning och reflektion i vissa fall. Mer information om hur du skapar en effektiv likhetsalgoritm för just din typ finns i Implementera likhet själv när en typ inte kan vara en post. 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 skapar egna klasser som åsidosätter
Equalsska du följa riktlinjerna som anges i Implementera likhetsjämförelse själv när en typ inte kan vara en record och Object.Equals(Object).
Relaterade avsnitt
Mer information finns i: