Risipa de key_press | Programare

Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Risipa de key_press | Programare - Programare .Net | Tehnici de programare | Tutoriale | Lectii si exemple

Valoare vs. referinta (I)

CLR prezinta doua tipuri de date: tip referinta si tip valoare. In urmatoarele articole vom face o analiza mai detaliata asupra celor doua categorii.

Tipurile valoare

In articolul Tipuri valoare am expus clasificarea acestora. Conform documentatiei SDK .Net, tipul valoare poate fi reprezentat de o structura (struct) sau de o enumerare (enum). De exemplu, structuri ca System.Int32 sau System.Boolean, Sytem.DayOfWeek sunt tipuri valoare. Este importantat de mentionat ca toate structurile si enumerarile deriva din tipul abstract System.ValueType care la randul lui deriva din clasa de baza System.Object.

Un tip valoare nu poate fi folosit ca baza pentru crearea unui alt tip valoare, toate tipurile valoare fiind sealed. Prin urmare, programatorul nu isi poate crea un tip valoare pornind de la un tip de baza ca Boolean sau Char. De aceea, un tip valoare nu poate avea membri abstracti. Urmatorul cod va genera eroare la compilare: The modifier ‘abstract’ is not valid for this item.

    public struct MyStruct
    {
       public abstract int Member { get; set; }
    }

In schimb, un tip valoare poate implementa una sau mai multe interfete.

    interface IMyInterface
    {
        void MyFirstMethod();
        void MySecondMethod(int value);
    }

    public struct MyStruct : IMyInterface
    {

        #region IMyInterface Members

        public void MyFirstMethod()
        {
            throw new NotImplementedException();
        }

        public void MySecondMethod(int value)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

Tipul valoare nu este supus GC, el se termina o data cu metoda, nu accepta finalizer si nu este referentiat de un pointer.

Tipurile referinta

Despre tipurile referinta s-a discutat in articolul Tipurile referinta. Ele sunt reprezentate de clase, interfete, delegati, siruri de caractere si tipul object (tipul de baza).

Tipurile referinta stocheaza in stack pointer-ul catre date, date care sunt stocate in heap. Memoria alocata tipurilor referinta este in heap, ceea ce poate conduce la o declansare a GC.

Asignarea unei variabile de tip referinta catre o alta instanta de tip de tip referinta va crea o copie care va referi aceeasi locatie din heap.

    class Agent
    {
        public int Code { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Agent a = new Agent();
            a.Code = 100;

            Agent b = new Agent();
            b = a;

            //100
            Console.WriteLine(b.Code);
            Console.ReadLine();
        }
    }

Tip valoarea sau tip referinta?

In procesul de proiectare al propriilor tipuri de date, programatorul trebuie sa aleaga cu atentie intre cele doua tipuri. Astfel, cateva situatii ce recomanda tipurile valoare pentru crearea unui tip nou:

  • o mai buna performanta intrucat nu sunt alocate in heap
  • tipul este simplu, immutable (sa nu aiba membri ce pot modifica campurile)
  • tipul nu este tip de baza si nu mosteneste un alt tip
  • marimea instantei este relativ mica, mai mica de 16 biti
  • marimea instantei este mare, dar tipul nu este este folosit in transmiterea parametrilor sau ca tip returnat (transmiterea parametrilor se face implicit prin valoare, ceea ce inseamna copierea valorilor campurilor si afectarea performantei)

Aceste doua tipuri de date prezentate de C# creeaza un paradox: in bibliotecile puse la dispozitie de FCL tipurile de referinta sunt cele mai intalnite, dar tipurile valoare sunt cele mai folosite de programatori. Chiar daca pentru dezvoltatorii de unmanaged C/C++ aceasta clasificare poate parea ciudata, ea contribuie la performanta aplicatiei. Sa ne imaginam cum ar fi fost daca pentru fiecare int cerut de programator ar fi avut loc intregul proces de alocare in memoria heap.

Category: Uncategorized

Your email address will not be published. Required fields are marked *

*