Jaký je rozdíl mezi struct a třídy v .NET?

hlasů
476

Jaký je rozdíl mezi struct a třídy v .NET?

Položena 16/08/2008 v 09:21
zdroj uživatelem
V jiných jazycích...                            


18 odpovědí

hlasů
804

NET, existují dvě kategorie typů, referenční typy a typy hodnot .

Struktury jsou typy hodnot a třídy jsou referenční typy .

Obecným Rozdíl je v tom, že reference druh žije na haldě a typ hodnoty žije inline, to znamená, že tam, kde je to vaše proměnná nebo oblast je definována.

Proměnná obsahující typ hodnoty obsahuje kompletní typ hodnoty hodnoty. Pro struct, to znamená, že proměnná obsahuje kompletní struct, se všemi svými poli.

Proměnná obsahující referenční typ obsahuje ukazatel, nebo odkaz někam jinam do paměti, kde se skutečná hodnota nachází.

To má jednu výhodu, začít s:

  • Typy hodnot vždy obsahuje hodnotu
  • referenční typy mohou obsahovat nulové -reference, což znamená, že neodkazují na nic vůbec v tuto chvíli

Interně referenční typ s jsou implementovány jako ukazatele, a s vědomím, že, a věděl, jak proměnná přiřazení práce, existují i jiné způsoby chování:

  • kopírování obsahu typu hodnota proměnné do jiné proměnné, zkopíruje celý obsah do nové proměnné, takže dvě různé. Jinými slovy, po kopii, se změní na jeden nebude mít vliv na ostatní
  • kopírování obsahu referenčního typu proměnné na jinou proměnnou, zkopíruje referenční, která vás znamená, že nyní mají dva odkazy na stejné někde jinde ukládání aktuálních dat. Jinými slovy, po kopii, změna data v jednom odkazu se zobrazí mít vliv na druhé straně také, ale jen proto, že jste opravdu jen při pohledu na stejná data na obou místech

Při deklarování proměnné nebo pole, zde je návod, jak tyto dva typy se liší:

  • Proměnná: hodnota typu žije v zásobníku, reference typu žije v zásobníku jako ukazatel někam do haldy paměti, kde skutečná paměť žije (i když na vědomí, Eric Lipperts článek série: Stack je implementace Detail ).
  • třídy / struct pole: typ hodnoty žije zcela uvnitř typu, typu reference žije uvnitř typu jako ukazatel někam do haldy paměti, kde skutečné paměti žije.
Odpovězeno 16/08/2008 v 19:41
zdroj uživatelem

hlasů
123

Krátké shrnutí každý:

Třídy pouze:

  • Může podporovat dědictví
  • Jsou referenční (ukazatel) Typy
  • Referenční může být nulový
  • Paměťový režii za novou instanci

Struktury pouze:

  • Nepodporuje dědičnost
  • Jsou typy hodnot
  • Jsou předány hodnotou (například celá čísla)
  • Nemůže mít null reference (pokud není použit Nullable)
  • Nemají režii paměť za novou instanci - pokud ‚krabici‘

Obě třídy a Struktury:

  • Jsou složené datové typy běžně používá k obsahovat několik proměnných, které mají nějaký logický vztah
  • Může obsahovat metody a události
  • Může podporovat rozhraní
Odpovězeno 04/10/2008 v 23:07
zdroj uživatelem

hlasů
27

NET prohlášení struct a třída rozlišovat mezi referenčními typy a typy hodnot.

Při předání kolem referenčního typu, je tam jen jeden ve skutečnosti uložena. Veškerý kód, který přistupuje k instance je přístup stejný jeden.

Při předání kolem typu hodnoty každý z nich je kopie. Veškerý kód pracuje na své vlastní kopii.

Toto může být ukázáno na příkladu:

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.

Pro třídu by to být jiná

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.

Třídy mohou být nic - odkaz může ukazovat na null.

Struktury jsou skutečná hodnota - mohou být prázdná, ale nikdy null. Z tohoto důvodu structs vždy výchozí konstruktor bez parametrů - potřebují ‚počáteční hodnotu‘.

Odpovězeno 16/08/2008 v 09:30
zdroj uživatelem

hlasů
16

Kromě všech odlišností popsaných v další odpovědi:

  1. Struktury nemohou mít explicitní bezparametrického konstruktor zatímco třída může
  2. Struktury nemohou mít destruktory , zatímco třída může
  3. Struktury nemohou dědit z jiného struct nebo třídy, zatímco třídy mohou dědit od jiné třídy. (Oba structs a třídy mohou implementovat z rozhraní.)

Pokud jste po videu vysvětluje všechny rozdíly, můžete si vyzkoušet Část 29 - C # Tutorial - Rozdíl mezi třídami a structs v jazyce C # .

Odpovězeno 14/06/2012 v 17:57
zdroj uživatelem

hlasů
14

Instance tříd jsou uloženy na spravované haldy. Všechny proměnné ‚obsahující‘ instanci jsou pouze odkaz na instanci na haldě. Předávání objektu do metoda vede kopii odkazu předávaný, nikoli samotný objekt.

Struktury (technicky, typy hodnot) jsou uloženy tam, kde jsou použity, podobně jako primitivní typ. Obsah může být kopírován do běhu kdykoli a bez vyvolání vlastní kopírovací konstruktor. Předávání typ hodnoty způsobu zahrnuje kopírování celou hodnotu, opět bez vyvolání jakékoliv přizpůsobitelný kód.

Rozdíl je vyrobena lépe názvy C ++ / CLI: „ref třída“ je třída, jak je popsáno dříve, „třída hodnota“ je třída, jak je popsáno druhé. Klíčová slova „třídy“ a „struct“ jak se používá v C # jsou prostě něco, co se musí naučit.

Odpovězeno 16/08/2008 v 13:16
zdroj uživatelem

hlasů
8

Od Microsoftu Volba mezi třídy a Struct ...

Jako pravidlo, většina druhů v rámci by měl být třídy. Existují však určité situace, ve kterých jsou charakteristiky typu hodnoty činí vhodnější použít structs.

Zvažte struct namísto třídy:

  • Pokud instance typu jsou malé a často krátkodobé, nebo jsou běžně součástí jiných objektů.

X Vyhněte se struct pokud typ má všechny dále uvedené charakteristiky:

  • To logicky představuje jediné hodnoty, podobně jako primitivní typy (int, double, atd).
  • Má velikost instance pod 16 bajtů.
  • Je neměnná. (nelze změnit)
  • Nebude muset být boxoval často.
Odpovězeno 14/05/2017 v 19:58
zdroj uživatelem

hlasů
5

Struktura vs třídě

Struktura je typ hodnoty tak, že je uložen v zásobníku, ale třída je referenční typ a je uložen na haldě.

Struktura nepodporuje dědičnost a polymorfismus, ale třída podporuje.

Ve výchozím nastavení všechny členy struct jsou veřejné, ale členové skupiny jsou ve výchozím nastavení soukromé povahy.

Jako struktura je typ hodnoty, nemůžeme přiřadit null do objektu struct, ale to není případ pro třídu.

Odpovězeno 06/11/2009 v 09:02
zdroj uživatelem

hlasů
4

Rozdíl mezi vzpěr a tříd -

  • Struktury jsou typ hodnoty vzhledem k tomu, Třídy jsou referenční typ .
  • Struktury jsou uloženy v zásobníku , zatímco Třídy jsou uloženy na haldě .
  • Typy hodnot držet svou hodnotu v paměti, kde jsou deklarovány, ale typové označení má odkaz na paměti objektu.
  • Typy Hodnota zničeny ihned poté, co rozsah je ztracena, zatímco referenční typ pouze variabilní zničí po ztrátě rozsah. Objekt je později zničený garbage collector.
  • Při kopírování struct do jiného struct, novou kopii tohoto struct dostane vytvořené modifikované jednoho struct nebude mít vliv na hodnotu druhého struct.
  • Při kopírování třídu do jiné třídy, pouze kopíruje reference variabilní.
  • Obě referenční variabilní bod na stejný objekt na haldě. Změna jedné proměnné ovlivní další referenční proměnné.
  • Struktury nemohou mít destruktory , ale třídy mohou mít destruktory.
  • Struktury nemohou mít explicitní bezparametrického konstruktérů zatímco třída může structs nepodporuje dědičnost, ale třídy dělat. Oba dědičnost podpora rozhraní.
  • Struktury jsou utěsněny typu .
Odpovězeno 05/01/2018 v 01:58
zdroj uživatelem

hlasů
4

Jen aby bylo kompletní, tam je další rozdíl při použití Equalsmetody, která je zděděné všemi třídami a struktur.

Umožňuje to, že máme třídu a strukturu:

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

a v hlavním způsobem, máme 4 objekty.

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

Pak:

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

Takže , struktury jsou vhodné pro numerické podobných předmětů, jako jsou body (uložit souřadnice x a y). A třídy jsou vhodné pro ostatní. I v případě, 2 lidé mají stejný název, výšku, váhu ..., jsou stále 2 osoby.

Odpovězeno 02/08/2017 v 13:34
zdroj uživatelem

hlasů
4

No, pro začátek, struct je předán podle hodnoty, nikoli odkazem. Struktury jsou vhodné pro relativně jednoduchých datových struktur, zatímco třídy mají mnohem větší flexibilitu z architektonického pohledu přes polymorfismus a dědičnost.

Jiní mohou pravděpodobně vám více detailů než já, ale já používám structs když struktura, že budu pro je jednoduchý.

Odpovězeno 16/08/2008 v 09:27
zdroj uživatelem

hlasů
3

Jak již bylo zmíněno: Třídy jsou reference typu, zatímco Struktury jsou typy hodnot se všemi důsledky.

Jako palec pravidlo rámcových pokynů design doporučuje používat structs namísto tříd, jestliže:

  • Má velikost instance pod 16 bajtů
  • To logicky představuje jediné hodnoty, podobně jako primitivní typy (int, double, atd.)
  • Je to neměnný
  • Nebude muset být boxoval často
Odpovězeno 23/09/2015 v 11:32
zdroj uživatelem

hlasů
3

Kromě základního rozdílu přístupové zadavatel, a některé výše uvedené bych chtěl přidat některé z hlavních rozdílů, včetně několika z výše uvedených s ukázkový kód s výkonem, který bude dávat jasnější představu o odkazu a hodnoty zmíněné

Struktury:

  • Jsou typy hodnot a nevyžadují přidělení haldy.
  • alokace paměti je jiná a je uložen v zásobníku
  • Užitečné pro malé datové struktury
  • Vliv na výkon, když míjíme hodnotu metody, míjíme celou strukturu dat a vše je předán do zásobníku.
  • Konstruktor jednoduše vrátí hodnotu struct sám (obvykle do dočasného umístění na zásobníku), a tato hodnota je pak kopírována podle potřeby
  • každé proměnné mají své vlastní kopie dat, a to není možné pro operace na jednom mít vliv na ostatní.
  • Nepodporují uživatelem specifikované dědictví, a to implicitně dědí z typu objektu

Třída:

  • Typ hodnota reference
  • Uloženy v haldy
  • Uložit odkaz na dynamicky přidělené objektu
  • Konstruktéři jsou spuštěny s novým provozovatelem, ale to neznamená, alokovat paměť na haldě
  • Více proměnných mohou mít odkaz na stejný objekt
  • Je možné, že operace na jedné proměnné ovlivní objekt odkazovaný jiné proměnné

ukázkový kód

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

Výstup

Počáteční hodnota Struct objektu je: 10

Uvnitř Struct Method uvnitř Method hodnota struct objekt je: 20

Po hodnotě volání metody z struct objekt je: 10

Počáteční hodnota třídy objektu je: 10

Uvnitř Class Method uvnitř Method hodnota třída objektu je: 20

Po hodnotě volání metody třídy objektu je: 20

Zde můžete jasně vidět rozdíl mezi výzvu hodnotou a volání odkazem.

Odpovězeno 29/05/2014 v 10:45
zdroj uživatelem

hlasů
2

Chcete-li přidat k ostatním odpovědi, je tam jeden zásadní rozdíl, který stojí za zmínku, a to je to, jak je uložen v paměti. To může mít velký vliv na výkon polí. Struktury jsou typy hodnot, takže uložit hodnotu v oblasti paměti, že jsou ukazující na, třídy jsou referenční typy, takže se odkazovat na třídu v oblasti paměti, že jsou ukazující na skutečná hodnota je uložena na jiném místě.

  • S struct, paměť je přiděleno v rámci třídy, který obsahuje pro ukládání dat.
  • S třídou bude třídu obsahující právě obsahovat ukazatel na nové třídy v jiné oblasti paměti.

To je také pravda, s poli, takže řada structs vypadá takto v paměti

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

Kde jako řada tříd vypadá následovně

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

Skutečné hodnoty se zajímáte nejsou ve skutečnosti uloženy v poli, ale na jiném místě v paměti.

Pro převážnou většinu aplikací tento rozdíl není opravdu záleží však na střední kódu výkonu to ovlivní lokalitu dat v paměti a mít velký vliv na výkonnost cache procesoru. Použití tříd, když jste mohli / měla použít structs se masivně zvýší počet vyrovnávací paměti mine na CPU.

Nejpomalejší věc moderní CPU dělá není lámání chleba čísla, to je načíst data z paměti, a L1 cache je mnohonásobně rychlejší než čtení dat z paměti RAM.

Odpovězeno 25/08/2015 v 13:00
zdroj uživatelem

hlasů
2
  1. Události deklarované ve třídě mají své + = a - = přístup automaticky uzamkne pomocí zámku (to) tak, aby byly bezpečné podprocesy (statické události jsou zamčené typeof třídu). Události deklarované v struct nemají + = a - = přístup automaticky zamkne. Zámek (to) pro struct nebude fungovat, protože můžete uzamknout pouze na vyjádření typové označení.

  2. Vytvoření instance struct nemůže způsobit úklid (pokud konstruktoru přímo nebo nepřímo vytváří referenční typ instance), zatímco vytvoření referenčního typu instanci může způsobit uvolnění paměti.

  3. Struct má vždy vestavěný veřejné výchozí konstruktor.

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

    To znamená, že struct je vždy bezprostředně použitelné, zatímco třída nemusí být, protože všechny její konstruktéři mohou být soukromé.

    class NonInstantiable
    {
        private NonInstantiable() // OK
        {
        }
    }
    
    struct Direct
    {
        private Direct() // Compile-time error
        {
        }
    }
    
  4. Struct nemohou mít destruktor. Destruktor je jen přepsání object.Finalize v přestrojení, a structs, jsou typy hodnot, nejsou předmětem garbage collection.

    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. Struct je implicitně uzavřen, třída není.
    Struct nemůže být abstraktní, třída může.
    Struct nelze volat: base () v jeho konstruktor, zatímco třídy bez explicitního základní třídy plechovky.
    Struct nemůže rozšířit jinou třídu, může třída.
    Struct nemůže vyhlásit chráněné členy (například pole, vnořené typy) Třída může.
    Struct nelze deklarovat abstraktní členy funkční, abstraktní třída může.
    Struct nemůže prohlásit virtuální členy funkční, může třída.
    Struct nelze deklarovat utěsněné členů funkci, může třída.
    Struct nemůže prohlásit potlačení členů funkce může třída.
    Jedinou výjimkou z tohoto pravidla je, že struct může přepsat virtuální metody System.Object, viz, rovná (), a GetHashCode (), a ToString ().

Odpovězeno 25/07/2011 v 06:24
zdroj uživatelem

hlasů
1

Existuje jeden zajímavý případ „class vs struct“ skládačky - situace, kdy budete muset vrátit několik výsledků z metody: vybrat, které použít. Pokud víte, že příběh ValueTuple - víte, že ValueTuple (struct) byla přidána, protože to by mělo být účinnější pak Tuple (class). Ale co to znamená v číslech? Dvě zkoušky: jedna je struct / třída, která mají 2 pole, ostatní se struct / třídy, které mají 8 polí (s rozměrem více než 4 - třída by měla zefektivnit pak struct hlediska procesor klíšťata, ale samozřejmě GC zatížení také je třeba zvážit ).

PS Dalším kritériem pro konkrétní případ ‚sturct nebo třídě s kolekcí‘ je zde: 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 |

Kód 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;
            }
        }
    }
}
Odpovězeno 18/12/2017 v 08:21
zdroj uživatelem

hlasů
1

Struktury jsou skutečná hodnota - mohou být prázdná, ale nikdy null

To je pravda, ale také vědomí, že od NET 2 structs podporují NULLABLE verze a C # dodává nějakou syntaktický cukr, aby bylo jednodušší.

int? value = null;
value  = 1;
Odpovězeno 16/08/2008 v 15:03
zdroj uživatelem

hlasů
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                                |
+-----------------------+------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------------------+
Odpovězeno 26/07/2018 v 10:43
zdroj uživatelem

hlasů
0

Každá proměnná nebo oblast primitivního typu hodnoty nebo struktury typu má jedinečnou instanci tohoto typu, včetně všech jeho oblastech (veřejné i soukromé). Naproti tomu, proměnné nebo pole referenční typy mohou držet null, nebo se může odkazovat na objekt, uložený na jiném místě, na které jakýkoliv počet dalších odkazů mohou rovněž existovat. Pole struct budou uloženy na stejném místě jako proměnné nebo oblasti tohoto typu konstrukce, který může být buď v zásobníku, nebo může být součástí jiného objektu haldy.

Vytvoření proměnné nebo pole typu primitivní hodnoty vytvoří ji s výchozí hodnotou; vytvoření proměnné nebo pole typu konstrukce vytvoří novou instanci, vytváření všech polí v něm ve výchozím způsobem. Vytvoření nové instance referenčního typu, začne tím, že vytvoří všechna pole v něm ve výchozím způsobem, a pak běží volitelný dodatečný kód v závislosti na typu.

Kopírování jedné proměnné nebo pole primitivního typu na jiný bude kopírovat hodnotu. Kopírování jedné proměnné nebo pole typu konstrukce na jiný bude kopírovat všechna pole (veřejné i soukromé) bývalého instance druhém případě. Kopírování jedné proměnné nebo pole referenčního typu na jiný způsobí, že tato se odkazovat na stejné instance jako bývalý (pokud existuje).

Je důležité si uvědomit, že v některých jazycích, jako je C ++, sémantické chování takového druhu, je nezávislá na tom, jak je uložena, ale to není pravda .NET. Je-li typ implementuje hodnota sémantiku proměnlivé, kopírování jednu proměnnou tohoto typu na jiný kopií vlastnosti první jiném případě odkazoval se na druhé, a za použití členem druhého mutovat, bude to znamenat, že druhá instance se má změnit , ale ne první. Je-li typ implementuje proměnlivé referenční sémantiku, kopírování jednu proměnnou do druhého a za použití členem druhého mutovat objekt bude mít vliv na předmět podle první proměnné; Typy s neměnnými sémantiky neumožňují mutaci, takže nezáleží na tom, zda sémanticky kopírování vytvoří novou instanci nebo vytváří další odkaz na první.

NET, je možné typy hodnot realizovat některý z výše uvedených sémantiky, za předpokladu, že všechny jejich polí může udělat totéž. Odkaz typu však může provádět pouze proměnlivé referenční sémantiku nebo neměnné sémantiku; Typy hodnot s poli proměnlivé referenční typy jsou omezeny buď prováděcí proměnlivých referenčních sémantiky nebo podivné hybridní sémantiky.

Odpovězeno 02/12/2011 v 01:10
zdroj uživatelem

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