Vra

Is dit moontlik in C# om 'n struktuur te hê met 'n lidveranderlike wat 'n klastipe is?Indien wel, waar word die inligting gestoor, op die stapel, die hoop of albei?

Was dit nuttig?

Oplossing

Ja, jy kan. Die wyser na die klas lid veranderlike gestoor op die stapel met die res van waardes die struct se en data die klas byvoorbeeld se gestoor word op die wal.

Structs kan ook bevat klas definisies as lede (innerlike klasse).

Hier is 'n paar baie nutteloos kode wat ten minste Versamel en loop om te wys dat dit moontlik is:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            MyStr m = new MyStr();
            m.Foo();

            MyStr.MyStrInner mi = new MyStr.MyStrInner();
            mi.Bar();

            Console.ReadLine();
        }
    }

    public class Myclass
    {
        public int a;
    }

    struct MyStr
    {
        Myclass mc;

        public void Foo()
        {
            mc = new Myclass();
            mc.a = 1;
        }

        public class MyStrInner
        {
            string x = "abc";

            public string Bar()
            {
                return x;
            }
        }
    }
}

Ander wenke

Die klas inhoud kry gestoor word op die wal.

'n verwysing na die klas (wat byna dieselfde as 'n wyser) kry gestoor met die struct inhoud. Waar die struct inhoud gestoor word, hang af van die vraag of dit 'n plaaslike veranderlike, metode parameter, of 'n lid van 'n klas, en of dit is doos of gevang deur 'n sluiting.

As een van die velde van 'n struktuur 'n klastipe is, sal daardie veld óf die identiteit van 'n klasvoorwerp of anders 'n nulverwysing.As die betrokke klasvoorwerp onveranderlik is (bv. string), sal die stoor van sy identiteit effektief ook die inhoud daarvan stoor.As die betrokke klasobjek veranderbaar is, sal die stoor van die identiteit egter 'n effektiewe manier wees om die inhoud te stoor as en slegs as die verwysing nooit in die hande van enige kode sal val wat dit kan muteer sodra dit in die veld gestoor is nie.

Oor die algemeen moet 'n mens vermy om veranderlike klastipes binne 'n struktuur te stoor, tensy een van twee situasies van toepassing is:

  1. Waarin 'n mens belangstel, is in werklikheid die identiteit van die klasobjek eerder as die inhoud daarvan.'n Mens kan byvoorbeeld 'n `Voormalige beheergrense`-struktuur definieer wat velde van tipe `Beheer` en `Regthoek` bevat, en verteenwoordig die `grense` wat beheer op een of ander tydstip gehad het, met die doel om later die beheer te kan herstel na sy vroeëre posisie.Die doel van die `Beheer`-veld sal nie wees om 'n afskrif van die beheer se toestand te hou nie, maar eerder om die beheer te identifiseer wie se posisie herstel moet word.Oor die algemeen moet die struktuur toegang vermy tot enige veranderlike lede van die voorwerp waarna dit 'n verwysing het, behalwe in gevalle waar dit duidelik is dat sodanige toegang verwys na die huidige veranderlike toestand van die betrokke voorwerp (bv.in 'n `CaptureControlPosition`- of `RestoreControlToCapturedPosition`-metode, of 'n `ControlHasMoved`-eienskap).
  2. Die veld is `privaat`, die enigste metodes wat dit lees doen dit met die doel om sy eienskappe te ondersoek sonder om die voorwerp self dit bloot te stel aan buitekode, en die enigste metodes wat dit skryf sal 'n nuwe objek skep, al die mutasies uitvoer wat ooit daarmee gaan gebeur, en stoor dan 'n verwysing na daardie voorwerp.'n Mens kan byvoorbeeld 'n "struktuur" ontwerp wat baie soos 'n skikking gedra, maar met waarde semantiek, deur die struktuur 'n skikking in 'n private veld te laat hou, en deur elke poging om die skikking te skryf 'n nuwe skikking met data te skep van die ou een, verander die nuwe skikking, en stoor die gewysigde skikking in daardie veld.Let daarop dat alhoewel die skikking self 'n veranderbare tipe sou wees, sal elke skikkingsinstansie wat ooit in die veld gestoor sou word effektief onveranderlik wees, aangesien dit nooit toeganklik sou wees deur enige kode wat dit kan muteer nie.

Let daarop dat scenario #1 redelik algemeen is met generiese tipes;byvoorbeeld, dit is baie algemeen om 'n woordeboek te hê waarvan die "waardes" die identiteite van veranderlike voorwerpe is;die opsomming van daardie woordeboek sal gevalle van terugstuur KeyValuePair wie se Value veld hou daardie veranderlike tipe.

Scenario #2 is minder algemeen.Daar is helaas geen manier om vir die samesteller te sê dat struktuurmetodes anders as eiendomsbepalings 'n struktuur sal wysig nie en die gebruik daarvan moet dus in leesalleen-kontekste verbied word;'n mens kan 'n struktuur hê wat soos 'n gedra het List<T>, maar met waarde semantiek, en ingesluit 'n Add metode, maar 'n poging om te bel Add op 'n lees-alleen-struktuur-instansie sal valse kode eerder as 'n samestellerfout genereer.Verder sal mutasiemetodes en eienskapstellers op sulke strukture oor die algemeen taamlik swak presteer.Sulke strukture kan nuttig wees wanneer hulle bestaan ​​as 'n onveranderlike omhulsel op 'n andersins-veranderbare klas;as so 'n struktuur nooit geboks word nie, sal prestasie dikwels beter as 'n klas wees.As presies een keer in boks (bv.deur na 'n koppelvlaktipe uitgesaai te word), sal prestasie oor die algemeen vergelykbaar wees met 'n klas.As dit herhaaldelik geboks word, kan prestasie baie slegter wees as 'n klas.

Dit is waarskynlik nie 'n aanbevole praktyk om dit te doen: sien http://msdn.microsoft.com/en-us/library/ms229017 (VS.85) Aspx

  

tipes Verwysing toegeken op die hoop klippe, en geheue bestuur is   hanteer word deur die vullis versamelaar.

     

Waarde tipes toegeken op die stapel of inline en is deallocated   wanneer hulle uitgaan van omvang.

     

In die algemeen, tipes waarde is goedkoper om te wys en deallocate.   Maar, as dit gebruik word in scenario's wat 'n beduidende vereis   bedrag van boks en unboxing, hulle swak presteer in vergelyking met   verwysing tipes.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top