1.Matrici

 - Reprezinta o totalitate de variabile de un singur tip si cu un nume comun pentru a le accesa. In C# maticele pot fi unidimensionala cit si multidimensionale. Mai des se folosesc matricile unidimensionale. matricele servesc la diferite scopuri, pentru ca reprezinta un mijloc comod de a uni variabilele. De exemplu, in matrice se poate de pastrat temperaturile maxime din zi, inregistrate pe parcursul unei luni, totalitatea cursurilior bursiere sau denmirile cartilor din biblioteca.

 - Principala prioritate al masivelor este organizarea datelor in asa fel incit sa fie usor de manipulat. Deci, daca avem un masiv care contine dividentele platite pentru un grupa de actiuni, atunci  organizind un acces ciclic asupra acestor elemente putem fara probleme sa calculam profitul mediu pentru aceste actiuni. In afara de aceasta, maticele permit organizarea datelor in asa fel incit usor le putem sorta.

 - Masivele in C# le putem folosi practic la fel ca si in alte limbaje de programare. Dar au o deosebire: ele sunt realizate sub forma de obiecte. Realizarea masivelor sub forma de obiecte ofera mai mute prioritati, una din ele fiind posibilitatea utilizarii masivelor nefolosite de metodele "colectorului de gunoi"


2.Matrici unidimensionale

 - Masiv unidimensional reprezinta o lista de variabile inlantuite, Asa liste se folosesc des in programare. De exemplu intr-un masiv unidimensional se pot pastra numerele utilizatorilor activi ai retelei sau nivelul mediu de succes al echipei de forbal.

 - Pentru a ne folosi de masive, in programa, trebuie de efectuat o procedura din doua etape, deoarece in C# masivele sunt realizate sub forma de obiecte. In primul rind trebuie de declarat variabila care se poate adresa masivului. In al doilea rind trebuie de creat un exemplar al masivului, folosind operatorul new. Asa deci, pentru declararea unui masiv unidimensional se foloseste forma

tip[] nume_masiv = new tip[nr_elemente];

unde tip determina tipul concret al elementelor rmasivului. Tipul elementelor determina tipul de date al fiecarui element care constituie masivul. Parantezele patrate [] indica ca este declarat un masiv unidimensional. Iar nr_elemente masivului determina numarul de elemente.

 - Vom analiza un exemplu concret: In linia de cod aratata mai jos se creaza un masiv de tip int, care este compus din 10 elemente si se leaga de variabila referinta la masiv, numitya sample:

int[] sample = new sample[10];

In variabila sample se pastreaza referinta la sona de memorie, alocata masivului de operatorul new. Aceasta zona de memorie trebuie sa fie destul de mare, ca in ea sa se poata pastra zece elemente ale maivului de tip int.

 - Declarea masivului se poate face si in felul urmator:

int[] sample; 
sample = new sample[10];

In acest caz variabila sample nu face referinta la vreun obiect fizic . Doar dupa executarea rindului al doilea aceasta variabila sface referinta la masiv.

 - Accesul la un element individual al masivului se face dupa index: Indexul este locatia elementului in masiv. In C# indexul primului element al tuturor masivelor este zero. In particular , masivull sample contine 10 elemente cu indexsii de la o la 9. Pentru a indexa un masiv este destul de indicat numarul elementului necesar in paranteze patrate. Asa cum primul element va si sample[0], ultimul va fi - sample[9].

Ex.: Atribuire valori elementelor masivului

//demo masiv unidimensional
using System;

namespace ArrayDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] sample = new int[10];
            int i;

            for (i = 0; i < 10; i = i + 1)
                sample[i] = i;

            for (i = 0; i < 10; i = i + 1)
                Console.WriteLine("sample[" + i + "]: " + sample[i]);

            Console.ReadKey(true);
        }
    }
}

Schematic masivul sample se poate reprezenta asa:

0 1 2 3 4 5 6 7 8 9
sample[0] sample[1] sample[2] sample[3] sample[4] sample[5] sample[6] sample[7] sample[8] sample[9]

 

Masivele se folosesc des in programare, pentru ca dau posibilitatea ca usor sa prelucram un numar mare de variabile interconectate. De exemplu in programa de mai jos se calculeaza media aritmetica al unui sir de valori, pastrate in masivul nums, care este prelucrat ciclic cu ajutorul operatorului for.

//calculare media aritmetica al unui sir de valori

using System;

namespace Average
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] nums = new int[10];
            int avg = 0;

            nums[0] = 99;
            nums[1] = 10;
            nums[2] = 100;
            nums[3] = 18;
            nums[4] = 78;
            nums[5] = 23;
            nums[6] = 63;
            nums[7] = 9;
            nums[8] = 87;
            nums[9] = 49;


            for (int i = 0; i < 10; i = i + 1)
                avg = avg + nums[i];

            avg = avg / 10;

            Console.WriteLine("media aritmetica: " + avg);

            Console.ReadKey(true);
        }
    }
}

Rezultatul executiei acestei programe este:  media arimetica: 53


3.Initializare masiv

 - Masivele se pot initializa la creare

tip[] nume_masiv = {val1, val2, val3, ..., valN};

Unde val1, val2, val3, ..., valN sunt valorile initiale, care se atribuie consecutiv de la stinga la dreapta si dupa ordinea indexarii. Pentru pastrarea initializatorilor masivului in C# automat se aloca destula memorie. Iar necesitatea operatorului new dispare. In calitate de exemplu vom prezenta varianta inbunatatita a programei care calculeaza media aritmetica:

 

//media aritmetica

using System;

namespace Average
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] nums = { 99, 10, 100, 18, 78,
                           23, 63, 9,   87, 49 };
                             
            int avg = 0;

            for(int i  = 0; i < 10; i++)
                 avg += nums[i];
             avg /= 10;

            Console.WriteLine("Media aritmetica: " + avg);

            Console.ReadKey(true);
        }
    }
}

Este curios faptul ca la initializarea masivului se poate de folosit si operatorul new., dar nu este necesar.

De ex:

 int[] nums = new int { 99, 10, 100, 18, 78,
                                 23, 63, 9,   87, 49 };

Aceasta fomra de initializare este folositoare in cazul in care, noului masiv i se atribuie o variabila deja existenta ca referinta la masiv:

   int[] nums;

   nums = new int[] { 99, 10, 100, 18, 78,
                              23, 63, 9,   87, 49 }; 
In acest caz variabila nums este declarata in primul operator si este initializata in al doilea.

 - La initializarea masivului, marimea lui se poate de indicat concret, dar aceasta marime trebuie sa corespunda cu numarul elementelor.

EX: Marimea masivului nums se da exact, si anume 10

 int[] nums = new int[10] { 99, 10, 100, 18, 78,
                                      23, 63, 9,   87, 49 };


4.Depasire limite masiv

 - limitele masivului sunt strict monitorizate in C#. Daca limitele nu se ajung sau se depasesc, atunci se genereaza eroare.

EX:

//depasire limita masiv

using System;

namespace ArrayErr
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] sample = new int[10];
                             
            for(int i  = 0; i < 100; i++)
                 sample[i] = i;
             
            Console.ReadKey(true);
        }
    }
}

Cind valoarea variabilei i trece de 10, apare situatia de exceptie de tip IndexOutOfRangeException, legata de depasirea limitelor la indexarea masivului.


5.Masive multidimensionale

 - Multidimensoinal esre un asa masiv care are doua sau mai multe dimensiuni. Accesul la fiecare element se face prin combinarea a doi sau mai multi indexi.


6.Masive bidimensionale

 - locul fiecarui element se determina prin doi indexi. Asa fel de masiv se poate de reprezentat ca un tabel, la rindurile caruia indica un index, iar la coloane  - alt index

 - In urmatorul rind de cod se declara un masiv bidimensional cu marimea 10x20

int[,] table = new int[10,20];

Trebuie de atras atentia la declararea acestui masiv. Dupa cum se vede ambele marimi sunt separate prin virgula. In prima parte al acestei declarari formula sintactica [,] inseamna, ca se creaza o variabila referinta la un masiv bidimensional. Daca alocam memorie cu operatorul new, atunci se foloseste urmatoarea sintaxa: 

int[10,20];

In aceasta declarare se creaza un masiv cu marimea de 10x20, dar si in acest caz marimile se separa prin virgula.

 - Pentru a accesa elemente trebuie de indicat ambii indexi, separati prin virgula. De exemplu in urmatorul rind de cod, elementului masivuluilui table cu indexii (3,5) i se atribuie valoarea 10:

table[3, 5] = 10;

- Vom arata un exemplu, unde initial se atribuie valori elementelor, apoi se afiseaza:

//demo masiv bidimensional

using System;

namespace TwoD
{
    class Program
    {
        static void Main(string[] args)
        {
            int t, i;
            int[,] table = new int [3, 4];

            for (t = 0; t < 3; ++t) {
                for (i = 0; i < 4; ++i) {
                    table[t, i] = (t * 4) + i + 1;
                    Console.Write(table[t,i] + " ");
                }
            }
            
             
            Console.ReadKey(true);
        }
    }
}

In acest exemplu elementul masivului table[0,0] va avea valoarea 1, elementul masivului table[0,1] va avea valoarea 2, elementul masivului table[0,3] va avea valoarea 3 etc.

//demo masiv bidimensional

using System;

namespace TwoD
{
    class Program
    {
        static void Main(string[] args)
        {
            int t, i;
            int[,] table = new int [3, 4];

            for (t = 0; t < 3; ++t) {
                for (i = 0; i < 4; ++i) {
                    table[t, i] = (t * 4) + i + 1;
                    Console.Write(table[t,i] + " ");
                }
            }
                      
            Console.ReadKey(true);
        }
    }
}


7.Masive cu trei si mai multe dimensiuni

 - Forma generala:

tip[,...,] nume_masiv = new tip[marime1, marime3, ... marimeN];

 - De exemplu, cream un masiv cu trei dimensiuni 4x10x3:

tip[ , , ] multidim = new int[4, 10, 3];

 - In exemplul urmator elementului masivului multidim cu coordonatele (2,4,1) ii atribuim valoarea 100:

multidim[2, 4, 1] = 100;

 - Vom exemplifica un masiv cu trei dimensiuni printr-o matrice de valori 3x3x3, apoi valorile acestui masiv se vor suma dupa una din diagonale:

 

//sama valorilor unei diagonale a masivului 3x3x3

using System;

namespace ThreeDMatrix
{
    class Program
    {
        static void Main(string[] args)
        {
            
            int[,,] m = new int [3, 3, 3];
            int sum = 0;
            int n = 1;

            for (int x = 0; x < 3; x++)
                for (int y = 0; y < 3; y++)
                    for (int z = 0; z < 3; z++)
                        m[x, y, z] = n++;

            sum = m[0, 0, 0] + m[1, 1, 1] + m[2, 2, 2];

            Console.WriteLine("Suma valorilor primei diagonale: " + sum);

            Console.ReadKey(true);
        }
    }
}

In rezultat se va afisa: Suma valorilor primei diagonale: 42


8.Initializare masive multidimensionale

 - Pentru a initializa un masiv multidimensional este suficient de inclus in acolade initializatorii fiecarii dimensiuni

 - Forma generala este:

tip[,] nume_masiv = {
    {val, val, val, ..., val},
    {val, val, val, ..., val},
    .
    .
    .
    {val, val, val, ..., val}
};

 Unde val semnifica valorilie initalizatoare, iar fiecare bloc intern reprezinta un rind. Prima valoare in fiecare rind se pastreaza pe prima pozitie in masiv, a doua valoarea pe a doua pozitie etc. Blocurile initializatorilor se separa prin virgule, iar dupa ultima acplada se pune punc si virgula

 - In calitate de exemplu mai jos este programa, in care masivul bidimensional sqrs se initializeaza cu numerele de la 1 la 10 si patratele acestor numere:

 

//initializare matrice

using System;

namespace squares
{
    class Program
    {
        static void Main(string[] args)
        {

            int[,] sqrs = { 
                              { 1, 1 },
                              { 2, 4 },
                              { 3, 9 },
                              { 4, 16 },
                              { 5, 25 },
                              { 6, 36 },
                              { 7, 49 },
                              { 8, 64 },
                              { 9, 81 },
                              { 10, 100 }
                            };
            
            int i , j;

            for (i = 0; i < 10; i++) {
                for (j = 0; j < 2; j++)
                    Console.Write(sqrs[i,j] + " ");
                Console.WriteLine();
            }
                
            Console.ReadKey(true);
        }
    }
}


9.Matrici esalonate

 - In exemplele de mai sus folosirea masivului bidimensional se crea ca o matrice dreptunghiulara. Masivul bidimensional se poate de reprezentat in forma de tabel, la care lungimea fiecarui rind ramine neschimbata pentru tot masivul. Dar in C# se poate de creat si o matrice de tip special, denumit matrice esalonata.Matrice esalonata repreainta un masiv de masive, in care lungimea fiecarui masiv poate fi diferita.Prin urmare matricea esalonata se poate de folosit la crearea unro tabele cu rindurile de diferite lunfimi.

 - Matricile esalonate se declara cu ajutorul parantezelor patrate in care se indica marimea. De exemplu, pentru declararea matricei esalonate forma generala este:

tip[ ] [ ] nume_masiv = new tip [marime] [ ];

Unde marime reprezinta numarul de rinduri in masiv. Memoria pentru rinduri se aloca individual, deaceia lungimea rindurilor poate fi diferita. De exemplu, in fragmentul urmator se declara matricea esalonata jagged. Memoria initial este alocta automat pentru prima dimensiune, apoi pentru fiecare dimensiune - manual:

int [][] jagged = new int[3][];
jagged[0] = new int[4];
jagged[1] = new int[3];
jagged[2] = new int[5];

Dupa executarea ecestui cod masivul jagged arata asa:

Acum este mai usor de inteles de ce aceste masive se numesc esalonate. Dupa crearea matricei esalonate accesul la elemente se face dupa indexul indicat in paranteze patrate.

EX: Elementului de pe pozitia (2,1) i se atgribuie valoarea 10;

jagged [2] [1] = 10;

Pentru matrici dreptunghiulare accesul la elemente se face astfel:  table[3, 5] = 10;

EX: creare matrice esalonata:

//matrice esalonata

using System;

namespace Jagged
{
    class Program
    {
        static void Main(string[] args)
        {
            int[][] jagged = new int[3][];
            jagged[0] = new int[4];
            jagged[1] = new int[3];
            jagged[2] = new int[5];

            int i;

            //salvare valori in primul masiv
            for (i = 0; i < 4; i++)
                jagged[0][i] = i;

            //salvare valori in al doilea masiv
            for (i = 0; i < 3; i++)
                jagged[1][i] = i;

            //salvare valori in al treilea masiv
            for (i = 0; i < 5; i++)
                jagged[2][i] = i;

            //extrage valori din primul masiv
            for (i = 0; i < 4; i++)
                Console.Write(jagged[0][i] + " ");

            Console.WriteLine();
            //extrage valori din al doilea masiv
            for (i = 0; i < 3; i++)
                Console.Write(jagged[1][i] + " ");

            Console.WriteLine();
            //extrage valori din al doilea masiv
            for (i = 0; i < 5; i++)
                Console.Write(jagged[2][i] + " ");

           Console.ReadKey(true);
        }
    }
}

Executarea acestei programe afiseaza urmatorul rezultat:

0 1 2 3
0 1 2
0 1 2 3 4

Masivele esalonate sunt utile doar in unele cazuri. Daca este nevoie de un masiv bidimensional, care nu va fi completat in totalitate, atunci masivele esalonate sunt structurile ideale. 

 - In masivele esalonate reprezinta masive de masive, si de asta nu este obligatoriu sa fie constituite din masive unidimensionale

EX: Creare masiv de masive bidimensionale:

int [ ] [ , ] jagged = new int [3] [ , ];

In urmatorul rind de cod elementului masivului jagged[0], i se atribuie o referinta la un masiv 4x2:

jagged[0] = new int  [4 , 2 ];

Iar in  urmatorul rind de cod elementului masivului jagged [0] [1,0], i se atribuie valoarea variabilei i:

jagged[0] [1,0] = i;


10.Atribuie referinte la masive 

 - Atribuire valoare unei variabile referinta la masiv altei variabile, inseamna ca ambele variabile fac referinta la unul si acelas masiv, sin in aceasta relatie masivul nu se deosebeste cu nimic de alte obiecte. Asa fel de atribuire nu duce la creare copie all masivului, nici copierea continutului unui masiv in altul.

In calitate de exemplu sa analizam programa urmatoare:


//atribuie referinta la masiv
using System;

namespace AssignARef
{
    class Program
    {
        static void Main(string[] args)
        {
            int i;
            int[] nums1 = new int[10];
            int[] nums2 = new int[10];

            for (i = 0; i < 10; i++) nums1[i] = i;
            for (i = 0; i < 10; i++) nums2[i] = -i;

            Console.Write("Continutul masivului nums1: ");
                for (i = 0; i < 10; i++)
                   Console.Write(nums1[i] + " ");
                       Console.WriteLine();

            Console.Write("Continutul masivului nums2: ");
                for (i = 0; i < 10; i++)
                    Console.Write(nums2[i] + " ");
                        Console.WriteLine();

            nums2 = nums1; // acuma nums2 face referinta la nums1

            Console.Write("Continutul masivului nums2\n" + "dupa atribuire: ");
            for (i = 0; i < 10; i++)
                Console.Write(nums2[i] + " ");
            Console.WriteLine();

            //In continuare operam cu masivul nums1 prin
            //intermediul variabilei referinta la masivul nums2

            nums2[3] = 99;

            Console.Write("Continutul masivului nums1 dupa modificare\n" + 
                "prin intermediul variabilei nums2: ");
            for (i = 0; i < 10; i++)
                Console.Write(nums1[i] + " ");
            Console.WriteLine();

            Console.ReadKey(true);

        }
    }
}

Dupa cum se observa, dupa  atribuire variabilei nums2 valoarea variabilei nums1, ambele variabile referinta la masiv fac referire la unu si acelas obiect.


11.Folosire proprietate Length 

 - Realizarea in C# al masivelor sub forma de obiecte ofera o multime de prioritati. Una din ele este ca , pentru fiecare masiv este legata proprietatea Length, care contine numarul de elemente din care este format masivul. Prin urmare,  fiecare masiv are o proprietate speciala care permite sa aflma lungimea lui. mai jos este un exemplu de programa care demonstreaza aceasta proprietate:

//folosire proprietate Lenght

using System;

namespace LenghtDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] nums = new int[10];

            Console.WriteLine("Lungimea masivului este " + nums.Length);

            //folosire Lenght pentru initializarea masivului nums.
            for (int i = 0; i < nums.Length; i++)
                nums[i] = i * i;

            //folosiren Lenght pentru afisare masiv nums.
            Console.Write("Continutul masivului: ");
            for (int i = 0; i < nums.Length; i++)
                Console.Write(nums[i] + " ");

            Console.WriteLine();

            Console.ReadKey(true);

        }
    }
}

 - La executarea cestei programe se afiseaza rezultatul urmator:

Lungimea masivului este 10

Continutul masivului: 0 1 4 9 16 25 36 49 64 81

 - Trebuie de atras atentia cum in clasa  LenghtDemo proprietatea nums.Lenght este folosita in ciclul for pentru a controla numarul de pasi ai ciclului. Fieacre masiv are lungimea sa ,de aceia aceasta proprietate se poate de folosit in locul metodei prin care se verifica manual lungimea masivului. Valoarea proprietatii Lenght nu reflecta numarul de elemente, care se folosesc cu adevarat. Ea cintine daor numarul de elemente ale masivului.

Cind se cere lungimea unui masiv multidimensional. atunci se returneaza numarul de elemente din care ar purea fi construit masivul, ca in exemplul urmator:

 

//folosire proprietate Lenght pentru un masiv tridimensional

using System;

namespace LenghtDemo3D
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,,] nums = new int[10, 5, 6];

            Console.WriteLine("Lungimea masivului este " + nums.Length);
                        
            Console.ReadKey(true);

        }
    }
}

 

 - La executarea cestei programe se afiseaza rezultatul urmator:

Lungimea masivului este 300

 - Proprietata Lenght contine numarul de elemente in total, nu se poate de folosit pentru a determina lungimea a unei dimensiuni doar.

Datorita existentei acesteri proprietati operatiile cu masive in multi algoritmi au fost simplificate, ce ce inseamna ca sunt mai sigure. In calitate de exemlu al proprietatii Lenght , vom crea o programa care schimba cu locul continutul unui masiv copiind-ul in ordine inversa in alt masiv:

//folosire proprietate Lenght pentru un masiv tridimensional

using System;

namespace RevCopy
{
    class Program
    {
        static void Main(string[] args)
        {
            int i, j;
            int[] nums1 = new int[10];
            int[] nums2 = new int[10];

            for (i = 0; i < nums1.Length; i++) nums1[i] = i;

            Console.Write("continutul initial al masivului este ");
            for (i = 0; i < nums2.Length; i++)
                Console.Write(nums1[i] + " ");

            Console.WriteLine();

            //copiere elemente din nums1 in nums2 in ordine inversa

            if (nums2.Length >= nums1.Length) // nums2 este destul de lung?
                for (i = 0, j = nums1.Length - 1; i < nums1.Length; i++, j--)
                    nums2[j] = nums1[i];
            Console.Write("Continutul masivului in ordine inversa ");
            for (i = 0; i < nums2.Length; i++)
                Console.Write(nums2[i] + " ");

            Console.WriteLine();

                Console.ReadKey(true);

        }
    }
}

 - La executarea cestei programe se afiseaza rezultatul urmator:

continutul initial al masivului este 0 1 2 3 4 5 6 7 8 9

Continutul masivului in ordine inversa  9 8 7 6 5 4 3 2 1 0

 - In acest exemplu proprietatea Lenght ajuta la executarea de functii importante, In primul rind, ea permite verificarea lungimii celui de-al doilea masiv si daca este suficienta pentru pastrarea tuturor valorilor din masivul initial. In al doilea rind, ea reprezinta conditia de sfirsit pentru ciclul for, in care se petrece copierea in ordine inversa. In acest exemplu simplu lungimile masivelor se pot calcula si fara Lenght, dar intr-o situatie mai complicata este destul de utila.


12.Folosire proprietate Length  la masivele esalonate

 - Un caz special reprezinta folosirea proprietatii Lenght la lucrul cu masivele esalonate. In aceasta situatie cu ajutorul lui Lenght se poate de obtunut lungimea fiecarui masiv care intra in componenta masivului esalonat. Sa examinam urmatoarea programa care imita lucrul Microprocesorului in retea formata din 4 noduri:

//folosire proprietate Lenght pentru un masiv esalonat

using System;

namespace Jagged
{
    class Program
    {
        static void Main(string[] args)
        {
            int[][] network_nodes = new int [4][];
            network_nodes[0] = new int[3];
            network_nodes[1] = new int[7];
            network_nodes[2] = new int[2];
            network_nodes[3] = new int[5];

            int i, j;

            //fabricare date despre folosirea MP
            for (i = 0; i < network_nodes.Length; i++)
                for (j = 0; j < network_nodes[i].Length; j++)
                    network_nodes[i][j] = i * j + 70;

            Console.WriteLine("Numarul total de noduri in retea: " +
                network_nodes.Length + "\n");

            for (i = 0; i < network_nodes.Length; i++) {
                for (j = 0; j < network_nodes[i].Length; j++) {
                    Console.Write("In retea sunt folosite " + i + 
                        " MP " + j + ": ");
                    Console.Write(network_nodes[i][j] + "% ");
                    Console.WriteLine();
                }
                Console.WriteLine();
            }

          Console.ReadKey(true);

        }
    }
}

trebuie de atras atentia la aceia cum proprietatea Lenght este folosita in masivul esalonat networks_nodes. Amintim ca, masivul bidimensional esalonat este un masiv de masive. Prin urmare cind se foloseste exepresia 

network_nodes.Length

in ea se determina numarul de masive, care se pastreaza in network_nodes(aici sunt 4 masive).Pentru obtinerea lungimii a oricarui din masive separat din masivul esalonat ne folosim de expresia:

network_nodes[0].Length

In cazul de mai sus se determina lungimea primului masiv.


13.Matrici tipizate indirect 

 - In versiunea C# 3.0 a aprut posibilitatea de a declara variabile cu ajutorul cuvintului cheie var. Acestea sunt variabile tipul carora este determinat de catre compilator, reesind din tipul care initializeaza expresia. Prin urmare , toate variabilele tipizate indicrect trebuie sa fie initializate. Folosind acelasi mecanizm, se poate de creat si masive tipizate indirect. Dupa regula aceste masive sunt destinate pentru folosirea unor anumite feluri de apeluri, care include elemente din limbajul LINQ. In restul cazurilor se foloseste forma obisnuita de declarare al masivelor.

 - Masivele tipizate indirect se declara cu ajutorul cuvintulului cheie var, dar fara parantezele [ ]. In afara de asta aceste masive trebuie initializate la declarare, pentru ca de tipul initializatorilor depinde   tipul elementelor acestui masiv. Toti initializatorii trebuie sa fie de acelasi tip. EX:

var vals = new[] {1,2,3,4,5};

In acest exemplu se creaza un masiv de tip int format din cinci elemente. Referinta la acest masiv se atribuie variabilei vals.Prin urmare tipul acestei variabile corespunde tipului int al masivului.In partea stinga lipsesc  parantezele [ ]. Iar in partea drepata, unde se initializeaza masivul, aceste paranteze sunt prezente. In acest context ele nu sunt necesare.

 - Sa analizam inca un exemplu in care se creaza un masiv bidimensional de tip double:

var vals = new[,] {{1.1, 2.2},{3.3, 4.4},{5.5, 6.6}};

In acest caz se formeaza un masiv 2x3.

 - Se poate de declarat si masive esalonate tipizate indirect. Drepr exemplu este programul urmator:

//demonstrare masiv esalonat tipizat indirect

using System;

namespace Jagged
{
    class Program
    {
        static void Main(string[] args)
        {
            var jagged = new[] { 
                new[] { 1, 2, 3, 4 },
                new[] { 9, 8, 7 },
                new[] { 11, 12, 13, 14, 15 }
            };

            for (int j = 0; j < jagged.Length; j++) {
                for (int i = 0; i < jagged[j].Length; i++)
                    Console.Write(jagged[j][i] + " ");

                Console.WriteLine();
            }
            Console.ReadKey(true);
        }
    }
}

Executarea acestei programe afiseaza umratoarele:

1 2 3 4
9 8 7 
11 12 13 14 15 

 - Trebuie de atras atentia la declararea masivului

var jagged = new[] { 
                new[] { 1, 2, 3, 4 },
                new[] { 9, 8, 7 },
                new[] { 11, 12, 13, 14, 15 }

Dupa cum se vede, operatorul new[ ] se foloseste in doua moduri. In primul rind acest operator creaza un masiv de masive. In al doilea rind el creaza fiecare masiv individual, marimea fiind numarul initializatorilor fiecarui masiv. Cum si era de asteptat , toti initializatorii ai diferitor masive trebuie sa fie de acelasi tip.