Vra

Wat is die verskil tussen struct en klas in NET?

Was dit nuttig?

Oplossing

In NET, is daar twee kategorieë van tipes, verwysing tipes en tipes waarde .

Structs is tipes waarde en klasse word verwysing tipes .

Die algemene verskil is dat 'n verwysing tipe woon op die hoop klippe, en 'n tipe waarde woon inline, dit is, waar dit ook al is jou veranderlike of in die veld word gedefinieer.

'n veranderlike met 'n tipe waarde bevat die hele tipe waarde waarde. Vir 'n struct, wat beteken dat die veranderlike bevat die hele struct, met al sy velde.

'n veranderlike met 'n verwysing tipe bevat 'n wyser, of 'n verwysing om iewers anders in die geheue waar die werklike waarde woon.

Dit het een voordeel, om te begin met:

  • tipes waarde bevat altyd 'n waarde
  • verwysing tipes kan bevat 'n null -reference, wat beteken dat hulle nie verwys na enigiets op die oomblik

Intern, verwysing tipe s geïmplementeer as wysers, en die wete dat, en weet hoe veranderlike opdrag werke, is daar ander gedragspatrone:

  • kopiëring van die inhoud van 'n tipe waarde veranderlike in 'n ander veranderlike, afskrifte van die hele inhoud in die nuwe veranderlike, maak die twee afsonderlike. Met ander woorde, na die kopie, veranderinge aan een sal geen invloed op die ander
  • kopiëring van die inhoud van 'n verwysing tipe veranderlike in 'n ander veranderlike, afskrifte van die verwysing, wat beteken dat jy nou twee verwysings na dieselfde elders stoor van die werklike data . Met ander woorde, na die kopie, die verandering van die data in een verwysing sal verskyn om die ander sowel raak, maar net omdat jy regtig net te kyk na die dieselfde data albei plekke

As jy verklaar veranderlikes of velde, hier is hoe die twee tipes verskil:

  • veranderlike: tipe waarde woon op die stapel, verwysing tipe woon op die stapel as 'n verwysing na iewers in hoop geheue waar die werklike geheue lewens (alhoewel noot Eric Lipperts artikel reeks :. Die stapel is 'n implementering Detail )
  • klas / struct-veld: tipe waarde leef heeltemal binne die tipe, verwysing tipe woon binne-in die tipe as 'n verwysing na iewers in hoop geheue waar die werklike geheue lewens .

Ander wenke

'n Kort opsomming van elk:

Klasse Slegs:

  • Kan ondersteun erfenis
  • Is verwysing (wyser) tipes
  • Die verwysing kan nul wees
  • Het geheue oorhoofse per nuwe byvoorbeeld

Structs Slegs:

  • Kan nie ondersteun erfenis
  • Is tipes waarde
  • Is verbygaan waarde (soos heelgetalle)
  • Kan nie 'n nul verwysing (tensy waarvoor geen nul mag gebruik word)
  • Moenie 'n geheue oorhoofse per nuwe geval - tensy 'doos'

Beide Klasse en Structs:

  • Is saamgestelde datatipes tipies gebruik word om 'n paar veranderlikes wat 'n paar logiese verhouding hê bevat
  • Kan metodes en gebeure bevat
  • Kan ondersteun interfaces

In NET onderskei die struct en klas verklarings tussen verwysing tipes en vorme waarde.

As jy slaag ronde 'n verwysing tipe is daar net een eintlik gestoor. Al die kode wat die geval toegang is toegang tot die dieselfde een.

As jy slaag ronde 'n waarde tipe elkeen is 'n afskrif. Al die kode is besig met sy eie kopie.

Dit kan aangetoon word met 'n voorbeeld:

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.

Vir 'n klas sal hierdie verskil

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.

Klasse kan niks wees -. Die verwysing kan verwys na 'n nul

Structs is die werklike waarde - hulle kan leë maar nooit nul wees. Om hierdie rede structs het altyd 'n verstek konstruktor met geen parameters - wat hulle nodig het 'n "begin waarde '

.

In bykomend tot al die verskille in die ander antwoorde beskryf:

  1. Structs kan nie 'n eksplisiete parameterless constructor terwyl 'n klas kan
  2. Structs kan nie destructors , terwyl 'n klas kan
  3. Structs kan nie erf van 'n ander struct of klas terwyl 'n klas kan besit van 'n ander klas. (Beide structs en klasse kan implementeer van 'n koppelvlak.)

As jy na 'n video wat verduidelik al die verskille, kan jy check out Deel 29 - C # Tutorial -. verskil tussen klasse en structs in C #

Gevalle van klasse gestoor word op die bestuur hoop. Alle veranderlikes 'bevat 'n geval is bloot 'n verwysing na die geval op die wal. Verby 'n voorwerp om 'n metode resultate in 'n afskrif van die verwysing aangeneem word, nie die voorwerp self.

Strukture (tegnies, waarde tipes) gestoor word waar dit gebruik word, baie soos 'n primitiewe soort. Die inhoud mag gekopieër deur die runtime te eniger tyd en sonder beroep 'n persoonlike kopie-constructor. Verby 'n waarde tipe na 'n metode behels die kopiëring van die hele waardeketting, weer sonder beroep enige aanpas kode.

Die onderskeid beter deur die C ++ / CLI name gemaak: "ref klas" is 'n klas as die eerste keer beskryf, "waarde klas" is 'n klas as tweede beskryf. Die term "klas" en "struct" soos gebruik deur C # is eenvoudig iets wat aangeleer moet word.

Die verskil tussen Structs en Klasse:

  • Structs is waarde tipe terwyl Klasse is verwysing tipe .
  • Structs gestoor word op die stapel terwyl Klasse word gestoor op die hoop .
  • Waarde tipes hou hul waarde in die geheue waar hulle verklaar, maar verwysing tipe het 'n verwysing na 'n voorwerp geheue.
  • Waarde tipes vernietig onmiddellik na die omvang verlore terwyl verwysing tipe net die veranderlike vernietig nadat die omvang verlore. Die voorwerp is later vernietig deur die vullis versamelaar.
  • As jy kopieer struct in 'n ander struct, 'n nuwe kopie van daardie struct kry geskep verander van een struct sal geen invloed op die waarde van die ander struct.
  • As jy 'n klas kopieer na 'n ander klas, dit net afskrifte van die verwysing veranderlike.
  • Beide die verwysing veranderlike punt om dieselfde voorwerp op die wal. Verandering aan een veranderlike sal beïnvloed die ander verwysing veranderlike.
  • Structs kan nie destructors het, maar klasse kan destructors het.
  • Structs kan nie eksplisiete parameterless vervaardigerskampioenskap terwyl 'n klas structs ondersteun nie erfenis, maar klasse doen. beide ondersteuning erfenis van 'n koppelvlak.
  • Structs verseël tipe .

Struktuur vs Klas

'n struktuur is nie 'n waarde tipe so dit geberg word op die stapel, maar 'n klas is 'n verwysing tipe en gestoor word op die wal.

'n struktuur ondersteun nie erfenis, en polimorfisme, maar 'n klas ondersteun beide.

By verstek, alle struct lede die openbare maar klaslede is by verstek private in die natuur.

As 'n struktuur is nie 'n waarde tipe, ons kan nie nul tot 'n struct voorwerp wys, maar dit is nie die geval vir 'n klas.

Net om dit volledig te maak, daar is nog 'n verskil by die gebruik van die Equals metode, wat geërf word deur alle klasse en strukture.

Kom ons sê ons het 'n klas en 'n struktuur:

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

en in die belangrikste metode, het ons 4 voorwerpe.

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;
}

Toe:

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

So , strukture geskik vir numeriese-agtige voorwerpe, soos punte (red x en y koördinate). En klasse is geskik vir ander. Selfs as 2 mense het dieselfde naam, lengte, gewig ..., hulle is nog steeds 2 mense.

Om toe te voeg tot die ander antwoorde, daar is een fundamentele verskil wat opmerklik is, en dit is hoe dit gestoor in die geheue. Dit kan 'n groot invloed op die prestasie van skikkings het. Structs is tipes waarde, sodat hulle slaan 'n waarde in die gebied van die geheue wat hulle verwys na, klasse is verwysing tipes, sodat hulle verwys 'n klas in die gebied van die geheue wat hulle verwys na die werklike waarde is elders gestoor.

  • Met 'n struct, geheue toegeken binne die met die klas vir die berging van die data.
  • Met 'n klas, die wat die klas sal net 'n verwysing na die nuwe klas bevat in 'n ander gebied van die geheue.

Dit is ook waar met skikkings, so 'n verskeidenheid van structs lyk soos volg in die geheue

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

Waar as 'n verskeidenheid van klasse lyk soos volg

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

Die werklike waardes jy belangstel in is nie eintlik gestoor in die skikking, maar elders in die geheue.

Vir 'n oorgrote meerderheid van aansoeke hierdie verskil maak nie regtig saak egter in 'n hoë werkverrigting kode sal lokaliteit van data te bewerkstellig binne die geheue en 'n groot impak op die prestasie van die CPU-kas. Die gebruik van klasse wanneer jy kan / moet gebruik structs sal op groot skaal die aantal kas mis te verhoog op die CPU.

Die stadigste ding wat 'n moderne SVE hoef nie getalle crunch, dis haal data vanaf die geheue, en 'n T1 kas treffer is baie keer vinniger as die lees van data uit RAM.

Wel, om mee te begin, 'n struct is verby waarde eerder as deur verwysing. Structs is goed vir relatief eenvoudige datastrukture, terwyl klasse het 'n baie meer buigsaamheid van 'n argitektoniese oogpunt via polimorfisme en erfenis.

Ander kan dalk meer detail gee jy as ek, maar ek gebruik structs wanneer die struktuur wat ek gaan vir is eenvoudig.

Behalwe die basiese verskil van toegang specific, en 'n paar genoem bo Ek wil graag by te voeg 'n paar van die groot verskille insluitend paar van die opsies met 'n kode monster met uitset genoem, wat 'n meer duidelike idee van die verwysing en waarde sal gee

Structs:

  • Is tipes waarde en vereis nie hoop toekenning.
  • Memory toekenning is anders en gestoor in stapel
  • Nuttig vir klein datastrukture
  • beïnvloed prestasie, wanneer ons waarde gee aan metode, slaag ons die hele datastruktuur en al is geslaag om die stapel.
  • Constructor eenvoudig gee die struct waarde self (tipies in 'n tydelike plek op die stapel), en hierdie waarde word dan kopieer soos nodig
  • Die veranderlikes het elk hul eie kopie van die data, en dit is nie moontlik vir operasies op een na die ander beïnvloed.
  • Moenie ondersteun gebruiker-gespesifiseerde erfenis, en hulle implisiet erf tipe voorwerp

Klas:

  • Reference Tipe waarde
  • gestoor in Heap
  • Bewaar 'n verwysing na 'n dinamiese toegeken voorwerp
  • Constructors opgeroep met die nuwe operateur, maar dit beteken nie geheue toeken op die wal
  • Verskeie veranderlikes kan 'n verwysing na dieselfde voorwerp
  • Dit is moontlik vir operasies op een veranderlike op die voorwerp verwys deur die ander veranderlike
  • beïnvloed

Code Voorbeeld

    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;
        }
    }

Uitgawe

Die aanvanklike waarde van struct voorwerp: 10

Binne struct Metode Binne Metode waarde van struct voorwerp: 20

Na Metode oproep waarde van struct voorwerp: 10

Die aanvanklike waarde van objekklas is: 10

In Klas Metode Binne Metode waarde van objekklas is: 20

Na Metode oproep waarde van objekklas is: 20

Hier kan jy duidelik sien die verskil tussen oproep deur waarde en roep deur verwysing.

  1. Events in 'n klas verklaar het hul + = en - = toegang outomaties gesluit deur 'n slot (hierdie) om hulle te laat veilig ryg (statiese gebeure gesluit op die typeof die klas). Gebeure in 'n struct verklaar het nie hul + = en - = toegang outomaties gesluit. A slot (hierdie) vir 'n struct sal nie werk nie, want jy kan net die slot op 'n verwysing tipe uitdrukking.

  2. Die skep van 'n struct byvoorbeeld kan nie veroorsaak dat 'n vullisverwydering (tensy die konstruktor direk of indirek skep 'n verwysing tipe instansie) terwyl die skep van 'n verwysing tipe instansie kan vullisverwydering veroorsaak.

  3. 'n struct altyd het 'n ingeboude in die openbaar verstek konstruktor.

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

    Dit beteken dat 'n struct is altyd instantiable terwyl 'n klas nie kan wees aangesien al sy konstruktors private kon wees.

    class NonInstantiable
    {
        private NonInstantiable() // OK
        {
        }
    }
    
    struct Direct
    {
        private Direct() // Compile-time error
        {
        }
    }
    
  4. 'n struct kan nie 'n destructor. A destructor is net 'n ignoreer van object.Finalize in vermomming, en structs, synde tipes waarde, is nie onderhewig aan vullisverwydering.

    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. 'n struct is implisiet verseël, 'n klas is nie.
    A struct kan nie abstrakte, 'n klas kan.
    A struct kan nie bel: basis () in sy konstruktor terwyl 'n klas met geen eksplisiete basis klas.
    A struct kan 'n ander klas, 'n klas kan nie uit te brei.
    A struct kan nie verklaar beskermde lede (byvoorbeeld velde, geneste tipes) 'n klas.
    A struct kan nie verklaar abstrakte funksie lede, 'n abstrakte klas.
    A struct kan nie verklaar virtuele funksie lede, 'n klas.
    A struct kan nie verklaar verseëlde funksie lede, 'n klas.
    A struct kan nie verklaar ignoreer funksie lede, 'n klas.
    Die een uitsondering op hierdie reël is dat 'n struct die virtuele metodes van System.Object kan ignoreer, naamlik, gelyk aan (), en GetHashCode (), en toString ().

Soos voorheen genoem:. Klasse is verwysing tipe terwyl Structs is tipes waarde met al die gevolge

As 'n duim van reël Framework Design riglyne beveel die gebruik van Structs in plaas van klasse as:

  • Dit het 'n geval grootte onder 16 grepe
  • Dit verteenwoordig logies 'n enkele waarde, soortgelyk aan primitiewe tipes (int, dubbel, ens.)
  • Dit is onveranderlike
  • Dit sal nie hoef te dikwels word doos
+-----------------------+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
|                       |                                                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            | Should be immutable                                                                                  | Mutable                                                                                           |
| Population            | In some situations                                                                                   | Majority of types in a framework should be classes                                                |
| Lifetime              | Short-lived                                                                                          | Long-lived                                                                                        |
| Destructor            | Cannot have                                                                                          | Can have                                                                                          |
| Inheritance           | Only from an interface                                                                               | Full support                                                                                      |
| Polymorphism          | 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 (+ When marked with nullable question mark in C# 8+)                                          |
| Abstract              | No                                                                                                   | When have abstract keyword                                                                        |
| Access Modifiers      | public, private, internal                                                                            | public, protected, internal, protected internal, private protected                                |
+-----------------------+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
  

Structs is die werklike waarde - hulle kan leë maar nooit nul wees

Dit is waar, maar ook daarop dat as van NET 2 structs ondersteun 'n waarvoor geen nul mag weergawe en C # verskaf 'n paar sintaktiese suiker te maak dit makliker om te gebruik.

int? value = null;
value  = 1;

Daar is 'n interessante geval van "klas vs struct" legkaart - situasie wanneer jy dit nodig om 'n paar resultate terugkeer van die metode: kies watter om te gebruik. As jy die ValueTuple storie ken - jy weet dat ValueTuple (struct) is bygevoeg omdat dit meer effektief moet wees dan tuple (klas). Maar wat beteken dit in getalle? Twee toetse: een is struct / klas wat 2 velde, ander met struct / klas wat 8 velde (met dimensie meer as 4 het - klas meer effektief moet word dan struct in terme verwerker bosluise, maar natuurlik GC vrag ook oorweeg moet word ).

post scriptum. Nog 'n maatstaf vir spesifieke geval 'sturct of klas met versamelings' is daar: 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 toets:

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;
            }
        }
    }
}

Elke veranderlike of in die veld van 'n primitiewe soort waarde of struktuur tipe het 'n unieke voorbeeld van die tipe, insluitend al sy velde (openbare en private). In teenstelling hiermee, kan veranderlikes of velde van verwysing tipes nul hou, of dalk verwys na 'n voorwerp, elders geberg, waaraan 'n aantal ander verwysings kan ook bestaan. Die velde van 'n struct sal gestoor word in die dieselfde plek as die veranderlike of in die veld van daardie struktuur tipe, wat óf deel van 'n ander hoop voorwerp kan wees op die stapel of mag wees .

Die skep van 'n veranderlike of in die veld van 'n primitiewe waarde tipe sal dit skep met 'n verstek waarde; die skep van 'n veranderlike of in die veld van 'n struktuur tipe sal 'n nuwe geval skep, die skep van alle velde daarin in die standaard wyse. Die skep van 'n nuwe byvoorbeeld van 'n verwysing tipe sal begin deur die skep van alle velde daarin in die standaard wyse, en dan hardloop opsionele ekstra kode afhangende van die tipe.

Die kopiëring van een veranderlike of in die veld van 'n primitiewe soort na 'n ander sal die waarde kopieer. Kopiëring een veranderlike of in die veld van tipe struktuur na 'n ander sal al die velde (openbare en private) van die eersgenoemde geval die laasgenoemde geval kopieer. Kopiëring een veranderlike of in die veld van verwysing tipe na 'n ander sal veroorsaak dat die laasgenoemde verwys na dieselfde geval as die voormalige (indien enige).

Dit is belangrik om daarop te let dat in sommige tale soos C ++, die semantiese gedrag van 'n tipe is onafhanklik van hoe dit geberg word, maar dit is nie waar van NET. As 'n tipe implemente wispelturig waarde semantiek, die kopiëring van een veranderlike van daardie tipe na 'n ander afskrifte van die eienskappe van die eerste om 'n ander geval, waarna verwys word deur die tweede, en met behulp van 'n lid van die tweede om te muteer dit sal die tweede geval laat verander , maar nie die eerste. As 'n tipe implemente wispelturig verwysing semantiek, die kopiëring van een veranderlike 'n ander en die gebruik van 'n lid van die tweede na die voorwerp muteer sal die om deur die eerste veranderlike verwys voorwerp beïnvloed; tipes met onveranderlike semantiek moenie toelaat dat mutasie, sodat dit nie semanties saak of kopiëring skep 'n nuwe geval of skep 'n ander verwysing na die eerste.

In NET, is dit moontlik vir tipe waarde aan enige van die bogenoemde semantiek te implementeer, met dien verstande dat al hul velde ook kan doen. 'N Verwysing tipe kan egter net wispelturig verwysing semantiek of onveranderlike semantiek te implementeer; tipes waarde met velde van wispelturig tipes verwysing is beperk tot óf die implementering wispelturig verwysing semantiek of vreemde baster semantiek.

scroll top