Hva er forskjellen mellom struct og klasse i .NET?

stemmer
507

Hva er forskjellen mellom struct og klasse i .NET?

Publisert på 16/08/2008 klokken 08:21
kilden bruker
På andre språk...                            


18 svar

stemmer
845

I NET, er det to kategorier av typer, referansetyper og verdityper .

Structs er verdityper og klasser er referansetyper .

Den generelle forskjellen er at en referansetype bor på haugen, og en verditype lever inline, det vil si hvor det er din variabel eller feltet er definert.

En variabel som inneholder en verditype inneholder hele verditype verdi. For en struct, som betyr at variabelen inneholder hele struct, med alle sine felt.

En variabel som inneholder en referansetype inneholder en peker, eller en referanse til et annet sted i hukommelsen hvor den faktiske verdien ligger.

Dette har en fordel, til å begynne med:

  • verdityper inneholder alltid en verdi
  • referansetyper kan inneholde null -reference, noe som betyr at de ikke refererer til noe som helst i øyeblikket

Internt referansetypen er s implementert som pekere, og vite at, og vite hvordan variable oppdrag fungerer, det er andre atferdsmønstre:

  • kopiere innholdet i en verditype variabel til en annen variabel, kopierer hele innholdet i ny variabel, noe som gjør de to distinkte. Med andre ord, etter at kopien, endres til en ikke vil påvirke andre
  • kopiere innholdet i en referansetype variabel i en annen variabel, kopierer referanse, som betyr at du nå har to referanser til det samme et annet sted lagring av faktiske data. Med andre ord, etter at kopi, endre dataene i en referanse vises til å påvirke den andre også, men bare fordi du egentlig bare å se på de samme dataene begge steder

Når du deklarerer variabler eller felt, her er hvordan de to typene avviker:

  • variabel: verditype bor på stakken, referansetypen lever på stakken som en peker til et sted i heap minne der selve minnet liv (men merk Eric Lipperts artikkelserien: The Stack er en implementering Detalj .)
  • klasse / struct-field: verdi typen bor fullstendig inne i typen, referansetypen lever inne type som en peker til et eller annet sted i haug minne hvor det faktiske minne lever.
Svarte 16/08/2008 kl. 18:41
kilden bruker

stemmer
138

En kort oppsummering av hvert:

Klasser bare i:

  • Kan støtte arv
  • Er referanse (pekeren) typer
  • Referansen kan være null
  • Har minne overhead per ny forekomst

Structs bare i:

  • Kan ikke støtte arv
  • Er verdityper
  • Er vedtatt av verdi (som heltall)
  • Kan ikke ha en nullreferanse (med mindre Kan ha nullverdier brukes)
  • Har du ikke et minne overhead per ny forekomst - med mindre 'eske'

Begge klasser og Structs:

  • Er sammensatte datatyper som vanligvis brukes til å inneholde noen variabler som har noen logisk sammenheng
  • Kan inneholde metoder og hendelser
  • Kan støtte grensesnitt
Svarte 04/10/2008 kl. 22:07
kilden bruker

stemmer
28

I NET struct og klassedeklarasjoner skille mellom referanse typer og verdityper.

Når du passerer rundt en referansetype er det bare én faktisk lagret. All den kode som får tilgang forekomsten aksesserer den samme.

Når du passerer rundt en verditype hver og en er en kopi. All koden fungerer på sin egen kopi.

Dette kan bli vist med et eksempel:

struct MyStruct 
{
    string MyProperty { get; set; }
}

void ChangeMyStruct(MyStruct input) 
{ 
   input.MyProperty = "new value";
}

...

// Create value type
MyStruct testStruct = new MyStruct { MyProperty = "initial value" }; 

ChangeMyStruct(testStruct);

// Value of testStruct.MyProperty is still "initial value"
// - the method changed a new copy of the structure.

For en klasse dette ville være annerledes

class MyClass 
{
    string MyProperty { get; set; }
}

void ChangeMyClass(MyClass input) 
{ 
   input.MyProperty = "new value";
}

...

// Create reference type
MyClass testClass = new MyClass { MyProperty = "initial value" };

ChangeMyClass(testClass);

// Value of testClass.MyProperty is now "new value" 
// - the method changed the instance passed.

Klasser kan være noe - referansen kan vise til en null.

Structs er den faktiske verdien - de kan være tomt, men aldri null. Av denne grunn structs alltid ha en standard konstruktør uten parametre - de trenger en 'startverdi'.

Svarte 16/08/2008 kl. 08:30
kilden bruker

stemmer
16

I tillegg til alle forskjeller beskrevet i andre svar:

  1. Structs kan ikke ha en eksplisitt parameterless konstruktør mens en klasse kan
  2. Structs kan ikke ha destructors , mens en klasse kan
  3. Structs kan ikke arve fra en annen struct eller klasse, mens en klasse kan arve fra en annen klasse. (Begge structs og klasser kan implementere fra et grensesnitt.)

Hvis du er ute etter en video som forklarer alle forskjellene, kan du sjekke ut Part 29 - C # Tutorial - Forskjellen mellom klasser og structs i C # .

Svarte 14/06/2012 kl. 16:57
kilden bruker

stemmer
14

Forekomster av klasser er lagret på den administrerte haug. Alle variabler 'inneholder' en forekomst er rett og slett en referanse til eksempel på haugen. Føring av et objekt til en metode fører til en kopi av at referansesignalet blir passert, ikke selve objektet.

Strukturer (teknisk verdityper) er lagret hvor de brukes, omtrent som en primitiv type. Innholdet kan kopieres ved runtime når som helst og uten å påberope en tilpasset kopi-konstruktøren. Passerer en verdi type til en fremgangsmåte som innebærer å kopiere hele verdi, igjen uten å påkalle en hvilken som helst passelig kode.

Skillet er gjort bedre av C ++ / CLI navn: "ref klassen" er en klasse som beskrevet først, "value klassen" er en klasse som beskrevet andre. Søkeordene "klasse" og "struct" som brukes av C # er bare noe som må læres.

Svarte 16/08/2008 kl. 12:16
kilden bruker

stemmer
9

Fra Microsofts Velge mellom klasse og Struct ...

Som en tommelfingerregel bør de fleste typer i et rammeverk være klasser. Det er imidlertid noen situasjoner der egenskapene til en verditype gjør det mer hensiktsmessig å bruke structs.

Vurdere en struct i stedet for en klasse:

  • Dersom forekomster av den type som er små og vanligvis kortvarig og er vanligvis innleiret i andre gjenstander.

X UNNGÅ en struct med mindre typen har alt av følgende egenskaper:

  • Det representerer logisk en enkelt verdi, lik den primitive typer (int, dobbel, etc.).
  • Den har en forekomst størrelse under 16 bytes.
  • Det er uforanderlig. (kan ikke endres)
  • Det trenger ikke å være innrammet ofte.
Svarte 14/05/2017 kl. 19:58
kilden bruker

stemmer
7

Forskjellen mellom Struts og klasser -

  • Structs er verditype , mens Klasser er referansetypen .
  • Structs er lagret på stabelen mens Klassene lagret på haugen .
  • Verdityper holder sin verdi i minnet hvor de er erklært, men referansetypen har en referanse til et objekt minne.
  • Verdi typer ødelagt umiddelbart etter at omfanget er tapt, mens referansetype eneste variabelen ødelegge etter omfanget er tapt. Formålet senere ødelagt av søppel kollektoren.
  • Når du kopierer struct inn i en annen struct, blir en ny kopi av struct opprettet modifisert av en struct vil ikke påvirke verdien av den andre struct.
  • Når du kopierer en klasse til en annen klasse, det bare kopierer referansen variable.
  • Både referanse variabelt punkt til det samme objektet på haugen. Bytt til en variabel vil påvirke den andre referansen variable.
  • Structs kan ikke ha destructors , men klasser kan ha destructors.
  • Structs kan ikke ha eksplisitte parameterless konstruktører mens en klasse kan structs støtter ikke arv, men klasser gjør. Både støtte arv fra et grensesnitt.
  • Structs er forseglet typen .
Svarte 05/01/2018 kl. 01:58
kilden bruker

stemmer
5

Struktur vs Class

En struktur er et verditype slik den er lagret på stabelen, men en klasse er en referansetype og er lagret på haugen.

En struktur støtter ikke arv og polymorfisme, men en klasse støtter begge.

Som standard alle struct medlemmene er offentlige, men klassen er som standard private i naturen.

Som en struktur er en verditype, kan vi ikke tildele null til en struct objekt, men det er ikke tilfelle for en klasse.

Svarte 06/11/2009 kl. 08:02
kilden bruker

stemmer
4

Bare for å gjøre det komplett, det er en annen forskjell når du bruker Equalsmetoden, som er arvet av alle klasser og strukturer.

Lar oss si at vi har en klasse og en struktur:

class A{
  public int a, b;
}
struct B{
  public int a, b;
}

og i den viktigste metoden, har vi 4 stedene.

static void Main{
  A c1 = new A(), c2 = new A();
  c1.a = c1.b = c2.a = c2.b = 1;
  B s1 = new B(), s2 = new B();
  s1.a = s1.b = s2.a = s2.b = 1;
}

Deretter:

s1.Equals(s2) // true
s1.Equals(c1) // false
c1.Equals(c2) // false
c1 == c2 // false

, er strukturer egnet for numeriske lignende gjenstander, som punkter (spare x og y-koordinater). Og klasser er egnet for andre. Selv om 2 personer har samme navn, høyde, vekt ..., er de fortsatt 2 personer.

Svarte 02/08/2017 kl. 13:34
kilden bruker

stemmer
4

Vel, for det første, er en struct vedtatt av verdi heller enn ved referanse. Structs er bra for relativt enkle datastrukturer, mens klasser har en mye mer fleksibilitet fra et arkitektonisk synspunkt via polymorfisme og arv.

Andre kan sikkert gi deg flere detaljer enn jeg, men jeg bruker structs når strukturen at jeg går for er enkel.

Svarte 16/08/2008 kl. 08:27
kilden bruker

stemmer
3

Som tidligere nevnt: Klassene er referansetype mens Structs er verdityper med alle konsekvenser.

Som en tommelfinger regel ramme Design Guidelines anbefaler å bruke Structs stedet for klasser dersom:

  • Den har en forekomst størrelse under 16 bytes
  • Det representerer logisk en enkelt verdi, lik den primitive typer (int, dobbel, etc.)
  • Det er uforanderlige
  • Det trenger ikke å være innrammet ofte
Svarte 23/09/2015 kl. 11:32
kilden bruker

stemmer
3

Hvis du vil legge til de andre svarene, det er en fundamental forskjell som er verdt å merke seg, og det er hvordan den er lagret i minnet. Dette kan ha en stor innvirkning på resultatene av arrays. Structs er verdityper, slik at de lagrer en verdi i området minne de peker på, klasser er referansetyper, slik at de refererer til en klasse i området minne de peker på, er den faktiske verdien er lagret andre steder.

  • Med en struct blir minne allokert innenfor den inneholdende klasse for lagring av data.
  • Med en klasse, vil inneholder klassen bare inneholde en peker til den nye klassen i et annet område av minnet.

Dette gjelder også med matriser, slik en rekke structs ser ut som dette i minnet

[struct][struct][struct][struct][struct][struct][struct][struct]

Der som en rekke klasser ser slik ut

[pointer][pointer][pointer][pointer][pointer][pointer][pointer][pointer]

De faktiske verdiene du er interessert i er faktisk ikke lagret i rekken, men andre steder i minnet.

For et stort flertall av søknader denne forskjellen ikke virkelig betyr noe, men i høy ytelse koden vil dette påvirke lokaliteten av data i minnet, og har en stor innvirkning på ytelsen til CPU cache. Ved hjelp av klasser når du kan / bør ha brukt structs vil massivt øke antall cache målet på CPU.

Den tregeste ting en moderne CPU gjør ikke knase tallene, er det hente data fra minnet, og en L1 cache hit er mange ganger raskere enn å lese data fra RAM.

Svarte 25/08/2015 kl. 13:00
kilden bruker

stemmer
3

Foruten den grunnleggende forskjellen på tilgang Specifier, og noen som er nevnt ovenfor vil jeg gjerne legge til noen av de store forskjellene inkludert noen av de ovennevnte med en kode prøve med utgang, noe som vil gi en mer klar idé om referansen og verdi

structs:

  • Er verdityper og ikke krever haug tildeling.
  • Minnetildeling er forskjellig og er lagret i stakken
  • Nyttig for små datastrukturer
  • Påvirke ytelsen, når vi passerer verdien til metode, passere vi hele datastrukturen og alt er gått til stabelen.
  • Konstruktør returnerer ganske enkelt struct verdi i seg selv (typisk i en midlertidig plassering på stabelen), og denne verdien blir deretter kopiert etter behov
  • Variablene har hver sin kopi av dataene, og det er ikke mulig for operasjoner på en for å påvirke den andre.
  • Støtter ikke brukerdefinert arv, og de implisitt arve fra type objekt

Klasse:

  • Reference Type verdi
  • Lagret i Heap
  • Lagre en referanse til en dynamisk allokert gjenstand
  • Konstruktører er startet med den nye operatøren, men det betyr ikke tildele minne på haugen
  • Flere variabler kan ha en referanse til det samme objektet
  • Det er mulig for operasjoner på en variabel å påvirke objektet referert av den andre variable

kode Sample

    static void Main(string[] args)
    {
        //Struct
        myStruct objStruct = new myStruct();
        objStruct.x = 10;
        Console.WriteLine("Initial value of Struct Object is: " + objStruct.x);
        Console.WriteLine();
        methodStruct(objStruct);
        Console.WriteLine();
        Console.WriteLine("After Method call value of Struct Object is: " + objStruct.x);
        Console.WriteLine();

        //Class
        myClass objClass = new myClass(10);
        Console.WriteLine("Initial value of Class Object is: " + objClass.x);
        Console.WriteLine();
        methodClass(objClass);
        Console.WriteLine();
        Console.WriteLine("After Method call value of Class Object is: " + objClass.x);
        Console.Read();
    }
    static void methodStruct(myStruct newStruct)
    {
        newStruct.x = 20;
        Console.WriteLine("Inside Struct Method");
        Console.WriteLine("Inside Method value of Struct Object is: " + newStruct.x);
    }
    static void methodClass(myClass newClass)
    {
        newClass.x = 20;
        Console.WriteLine("Inside Class Method");
        Console.WriteLine("Inside Method value of Class Object is: " + newClass.x);
    }
    public struct myStruct
    {
        public int x;
        public myStruct(int xCons)
        {
            this.x = xCons;
        }
    }
    public class myClass
    {
        public int x;
        public myClass(int xCons)
        {
            this.x = xCons;
        }
    }

Produksjon

Initialverdi på Struct Objektet er: 10

Inne Struct Metode inne Metode verdi av Struct objekt er: 20

Etter Metode samtale verdien av Struct Objektet er: 10

Initial verdi av klasse objektet er: 10

Inne i klasse Metode inne Metode verdi av klasse objektet er: 20

Etter metodekall verdi av klasse objektet er: 20

Her kan du tydelig se forskjellen mellom samtale i verdi og ringe ved referanse.

Svarte 29/05/2014 kl. 09:45
kilden bruker

stemmer
2
  1. Arrangementer er erklært i en klasse har sine + = og - = adgang automatisk låses via en lås (dette) for å gjøre dem træ sikker (statiske arrangementer er låst på typeof klassen). Hendelser deklarert i en struct ikke har sin + = og - = tilgang automatisk låst. En lås (dette) for en struct ville ikke fungere, siden du bare kan låse på en referansetype uttrykk.

  2. Oppretting av en struct eksempel kan ikke føre til en søppeloppsamlings (med mindre konstruktøren direkte eller indirekte danner et referansetype eksempel), mens skape et referansetype eksempel kan forårsake sanering.

  3. En struct alltid har en innebygd offentlig standardkonstruktør.

    class DefaultConstructor
    {
        static void Eg()
        {
            Direct     yes = new   Direct(); // Always compiles OK
            InDirect maybe = new InDirect(); // Compiles if constructor exists and is accessible
            //...
        }
    }
    

    Dette betyr at en struct er alltid en forekomst mens en klasse kanskje ikke siden alle sine konstruktører kan være privat.

    class NonInstantiable
    {
        private NonInstantiable() // OK
        {
        }
    }
    
    struct Direct
    {
        private Direct() // Compile-time error
        {
        }
    }
    
  4. En struct kan ikke ha en destructor. En destructor er bare en overstyring av object.Finalize i forkledning, og structs, være verdityper, er ikke gjenstand for søppelrydding.

    struct Direct
    {
        ~Direct() {} // Compile-time error
    }
    class InDirect
    {
        ~InDirect() {} // Compiles OK
    }
    
    And the CIL for ~Indirect() looks like this:
    
    .method family hidebysig virtual instance void
            Finalize() cil managed
    {
      // ...
    } // end of method Indirect::Finalize
    
  5. En struct implisitt forseglet, en klasse er det ikke.
    En struct kan ikke være abstrakt, en klasse kan.
    En struct kan ikke ringe: base () i sin konstruktør mens en klasse uten eksplisitt base klasse kan.
    En struct kan ikke forlenge en annen klasse, en klasse kan.
    En struct kan ikke erklære beskyttede elementer (for eksempel, felt, nestede typer) en klasse kan.
    En struct kan ikke erklære abstrakte funksjon medlemmer, er en abstrakt klasse kan.
    En struct kan ikke erklære virtuelle funksjons medlemmer, en klasse kan.
    En struct kan ikke erklære forseglede funksjons medlemmer, en klasse kan.
    En struct kan ikke erklære styringsfunksjon medlemmer, en klasse kan.
    Det eneste unntak fra denne regel er at et struct kan overstyre de virtuelle metoder for System.Object, nemlig lik (), og GetHashCode (), og toString ().

Svarte 25/07/2011 kl. 05:24
kilden bruker

stemmer
1

Det er en interessant tilfelle av "class vs struct" puzzle - situasjon når du trenger å komme tilbake flere resultater fra metoden: velger å bruke. Hvis du kjenner ValueTuple historien - du vet at ValueTuple (struct) ble satt fordi det bør være mer effektive da Tuppel (klasse). Men hva betyr det i tall? To forsøk: ett er struct / klasse som har 2 felt, andre med struct / klasse som har 8 felt (med dimensjon mer enn 4 - klasse skal bli mer effektiv da konstruere i form prosessor blodmidd, men selvfølgelig GC belastning også bør tas i betraktning ).

PS En annen målestokk for konkrete tilfellet 'sturct eller klasse med samlinger' er der: https://stackoverflow.com/a/45276657/506147

BenchmarkDotNet=v0.10.10, OS=Windows 10 Redstone 2 [1703, Creators Update] (10.0.15063.726)
Processor=Intel Core i5-2500K CPU 3.30GHz (Sandy Bridge), ProcessorCount=4
Frequency=3233540 Hz, Resolution=309.2586 ns, Timer=TSC
.NET Core SDK=2.0.3
  [Host] : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT
  Clr    : .NET Framework 4.7 (CLR 4.0.30319.42000), 64bit RyuJIT-v4.7.2115.0
  Core   : .NET Core 2.0.3 (Framework 4.6.25815.02), 64bit RyuJIT


            Method |  Job | Runtime |     Mean |     Error |    StdDev |      Min |      Max |   Median | Rank |  Gen 0 | Allocated |
------------------ |----- |-------- |---------:|----------:|----------:|---------:|---------:|---------:|-----:|-------:|----------:|
  TestStructReturn |  Clr |     Clr | 17.57 ns | 0.1960 ns | 0.1834 ns | 17.25 ns | 17.89 ns | 17.55 ns |    4 | 0.0127 |      40 B |
   TestClassReturn |  Clr |     Clr | 21.93 ns | 0.4554 ns | 0.5244 ns | 21.17 ns | 23.26 ns | 21.86 ns |    5 | 0.0229 |      72 B |
 TestStructReturn8 |  Clr |     Clr | 38.99 ns | 0.8302 ns | 1.4097 ns | 37.36 ns | 42.35 ns | 38.50 ns |    8 | 0.0127 |      40 B |
  TestClassReturn8 |  Clr |     Clr | 23.69 ns | 0.5373 ns | 0.6987 ns | 22.70 ns | 25.24 ns | 23.37 ns |    6 | 0.0305 |      96 B |
  TestStructReturn | Core |    Core | 12.28 ns | 0.1882 ns | 0.1760 ns | 11.92 ns | 12.57 ns | 12.30 ns |    1 | 0.0127 |      40 B |
   TestClassReturn | Core |    Core | 15.33 ns | 0.4343 ns | 0.4063 ns | 14.83 ns | 16.44 ns | 15.31 ns |    2 | 0.0229 |      72 B |
 TestStructReturn8 | Core |    Core | 34.11 ns | 0.7089 ns | 1.4954 ns | 31.52 ns | 36.81 ns | 34.03 ns |    7 | 0.0127 |      40 B |
  TestClassReturn8 | Core |    Core | 17.04 ns | 0.2299 ns | 0.2150 ns | 16.68 ns | 17.41 ns | 16.98 ns |    3 | 0.0305 |      96 B |

Kode test:

using System;
using System.Text;
using System.Collections.Generic;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Attributes.Columns;
using BenchmarkDotNet.Attributes.Exporters;
using BenchmarkDotNet.Attributes.Jobs;
using DashboardCode.Routines.Json;

namespace Benchmark
{
    //[Config(typeof(MyManualConfig))]
    [RankColumn, MinColumn, MaxColumn, StdDevColumn, MedianColumn]
    [ClrJob, CoreJob]
    [HtmlExporter, MarkdownExporter]
    [MemoryDiagnoser]
    public class BenchmarkStructOrClass
    {
        static TestStruct testStruct = new TestStruct();
        static TestClass testClass = new TestClass();
        static TestStruct8 testStruct8 = new TestStruct8();
        static TestClass8 testClass8 = new TestClass8();
        [Benchmark]
        public void TestStructReturn()
        {
            testStruct.TestMethod();
        }

        [Benchmark]
        public void TestClassReturn()
        {
            testClass.TestMethod();
        }


        [Benchmark]
        public void TestStructReturn8()
        {
            testStruct8.TestMethod();
        }

        [Benchmark]
        public void TestClassReturn8()
        {
            testClass8.TestMethod();
        }

        public class TestStruct
        {
            public int Number = 5;
            public struct StructType<T>
            {
                public T Instance;
                public List<string> List;
            }

            public int TestMethod()
            {
                var s = Method1(1);
                return s.Instance;
            }

            private StructType<int> Method1(int i)
            {
                return Method2(++i);
            }

            private StructType<int> Method2(int i)
            {
                return Method3(++i);
            }

            private StructType<int> Method3(int i)
            {
                return Method4(++i);
            }

            private StructType<int> Method4(int i)
            {
                var x = new StructType<int>();
                x.List = new List<string>();
                x.Instance = ++i;
                return x;
            }
        }

        public class TestClass
        {
            public int Number = 5;
            public class ClassType<T>
            {
                public T Instance;
                public List<string> List;
            }

            public int TestMethod()
            {
                var s = Method1(1);
                return s.Instance;
            }

            private ClassType<int> Method1(int i)
            {
                return Method2(++i);
            }

            private ClassType<int> Method2(int i)
            {
                return Method3(++i);
            }

            private ClassType<int> Method3(int i)
            {
                return Method4(++i);
            }

            private ClassType<int> Method4(int i)
            {
                var x = new ClassType<int>();
                x.List = new List<string>();
                x.Instance = ++i;
                return x;
            }
        }

        public class TestStruct8
        {
            public int Number = 5;
            public struct StructType<T>
            {
                public T Instance1;
                public T Instance2;
                public T Instance3;
                public T Instance4;
                public T Instance5;
                public T Instance6;
                public T Instance7;
                public List<string> List;
            }

            public int TestMethod()
            {
                var s = Method1(1);
                return s.Instance1;
            }

            private StructType<int> Method1(int i)
            {
                return Method2(++i);
            }

            private StructType<int> Method2(int i)
            {
                return Method3(++i);
            }

            private StructType<int> Method3(int i)
            {
                return Method4(++i);
            }

            private StructType<int> Method4(int i)
            {
                var x = new StructType<int>();
                x.List = new List<string>();
                x.Instance1 = ++i;
                return x;
            }
        }

        public class TestClass8
        {
            public int Number = 5;
            public class ClassType<T>
            {
                public T Instance1;
                public T Instance2;
                public T Instance3;
                public T Instance4;
                public T Instance5;
                public T Instance6;
                public T Instance7;
                public List<string> List;
            }

            public int TestMethod()
            {
                var s = Method1(1);
                return s.Instance1;
            }

            private ClassType<int> Method1(int i)
            {
                return Method2(++i);
            }

            private ClassType<int> Method2(int i)
            {
                return Method3(++i);
            }

            private ClassType<int> Method3(int i)
            {
                return Method4(++i);
            }

            private ClassType<int> Method4(int i)
            {
                var x = new ClassType<int>();
                x.List = new List<string>();
                x.Instance1 = ++i;
                return x;
            }
        }
    }
}
Svarte 18/12/2017 kl. 08:21
kilden bruker

stemmer
1

Structs er den faktiske verdien - de kan være tom, men aldri null

Dette er sant, men også oppmerksom på at fra og med .NET 2 structs støtte en Kan ha nullverdier versjon og C # leverer noen syntaktisk sukker for å gjøre det enklere å bruke.

int? value = null;
value  = 1;
Svarte 16/08/2008 kl. 14:03
kilden bruker

stemmer
0
+-----------------------+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
|                       |                                                Struct                                                |                                               Class                                               |
+-----------------------+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
| Type                  | Value-type                                                                                           | Reference-type                                                                                    |
| Where                 | On stack / Inline in containing type                                                                 | On Heap                                                                                           |
| Deallocation          | Stack unwinds / containing type gets deallocated                                                     | Garbage Collected                                                                                 |
| Arrays                | Inline, elements are the actual instances of the value type                                          | Out of line, elements are just references to instances of the reference type residing on the heap |
| Aldel Cost            | Cheap allocation-deallocation                                                                        | Expensive allocation-deallocation                                                                 |
| Memory usage          | Boxed when cast to a reference type or one of the interfaces they implement,                         | No boxing-unboxing                                                                                |
|                       | Unboxed when cast back to value type                                                                 |                                                                                                   |
|                       | (Negative impact because boxes are objects that are allocated on the heap and are garbage-collected) |                                                                                                   |
| Assignments           | Copy entire data                                                                                     | Copy the reference                                                                                |
| Change to an instance | Does not affect any of its copies                                                                    | Affect all references pointing to the instance                                                    |
| Mutability            | Mutable                                                                                              | Should be immutable                                                                               |
| Population            | Majority of types in a framework should be classes                                                   | In some situations                                                                                |
| Lifetime              | Long-lived                                                                                           | Short-lived                                                                                       |
| Destructor            | Can't have                                                                                           | Can have                                                                                          |
| Inheritence           | Only from an interdace                                                                               | Full-support                                                                                      |
| Polymotphism          | No                                                                                                   | Yes                                                                                               |
| Sealed                | Yes                                                                                                  | When have sealed keyword                                                                          |
| Constructor           | Can not have explicit parameterless constructors                                                     | Any constructor                                                                                   |
| Null-assignments      | When marked with nullable question mark                                                              | Yes                                                                                               |
| Abstract              | No                                                                                                   | When have abstract keyword                                                                        |
| Access Modifiers      | public, private, internal                                                                            | public, protected, internal, protected internal, private protected                                |
+-----------------------+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
Svarte 26/07/2018 kl. 10:43
kilden bruker

stemmer
0

Hver variabel eller felt av en primitiv verdi type eller struktur type har en unik forekomst av denne typen, inkludert alle sine felt (offentlige og private). I motsetning til dette kan variabler eller felt av referanse typer holde null, eller kan henvise til et objekt, som er lagret et annet sted, til hvilket et hvilket som helst antall av andre referanser, kan også eksistere. Områdene for en struct vil bli lagret på samme sted som det variable eller felt av den strukturtype, som kan være enten på stabelen, eller kan være en del av et annet objekt haug.

Opprette en variabel eller felt av en primitiv verdi type vil lage den med en standardverdi; opprettelse av et variabelt eller felt av en strukturtype vil skape en ny forekomst, og skaper alle feltene i denne på standard måte. Skape en ny forekomst av en referansetype vil begynne med å opprette alle feltene i denne på standard måte, og deretter kjører valgfri tilleggskode, avhengig av typen.

Kopiering av en variabel eller felt av en primitiv type til en annen vil kopiere verdi. Kopiering av en variabel eller felt av strukturtype til en annen, vil kopiere alle feltene (offentlige og private) i det tidligere tilfellet til det sistnevnte tilfelle. Kopiering av en variabel eller felt av referansetype til en annen vil føre til at sistnevnte for å henvise til samme forekomst som den førstnevnte (hvis noen).

Det er viktig å merke seg at i noen språk som C ++, den semantiske oppførselen til en type er uavhengig av hvordan den er lagret, men det er ikke sant av .NET. Hvis en type som implementerer foranderlig verdi semantikk, å kopiere en variabel av den type til en annen kopier egenskapene til det første til et annet tilfelle, referert til av den andre, og ved hjelp av et medlem av den andre for å mutere det vil føre til at andre tilfellet må endres , men ikke den første. Hvis en type som implementerer foranderlig referanse semantikk, å kopiere en variabel til en annen, og ved hjelp av et medlem av den andre for å mutere objektet vil påvirke objektet referert til ved den første variable; typer med uforanderlige semantikk tillater ikke mutasjon, så det spiller ingen rolle semantisk om kopiering oppretter en ny forekomst eller skaper annen referanse til den første.

I NET, er det mulig for verdityper å implementere noen av de ovennevnte semantikk, forutsatt at alle deres felt kan gjøre det samme. En referansetypen, men kan bare gjennomføre foranderlig referanse semantikk eller uforanderlige semantikk; lige typer med foranderlig felt av referansetyper er begrenset til enten å implementere foranderlig referanse semantikk eller rar hybrid semantikk.

Svarte 02/12/2011 kl. 00:10
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more