Generično programiranje

Generično programiranje je način programiranja, kjer so postopki napisani v smislu tipov, ki bodo natanno določeni pozneje, in so instanccirani šele, ko jih potrebujemo za konkretne tipe. Generični tipi vsebujejo enega ali več tipskih parametrov, ki določajo dejanske tipe, ki so vključeni v definicijo generičnega tipa.

Generičnost v .NET uredi

Generični tipi so bili dodani v različici 2.0 ogrodja .NET v novembru 2005. V nasprotju z javo so kenerični tipi prvorazredni konstrukti izvajalskega okolja, kar omogoča refleksijo z ogranitvijo generičnih tipov in izognitev nekaterim omejitvam v javi (npr. nezmožnost tvorjenja generičnih tabel).[1][2] To pomeni tudi, da ni poslabšanja performanc zaradi pretvorb v času izvajanja in običajno dragih pretvorb med vrednostnimi in referenčnimi tipi.

.NET pozna šest vrst omejitev za henerične tipe (z uporabo ključne besede "where"), npr. omejitev na vrednostne tipe, na razrede, na tipe, ki imajo konstruktor, in na tipe, ki implementirajo zahtevane vmesnike.

Spodnji primer prikazije omejitev na tipe, ki implementirajo določen vmesnik (v tem primeru ICompatible<T>, ki je sam generični vmesnik, ki vsebuje isti tipskki parameter T, kot generična metoda "MakeAtLeast<T>"):

using System;

class Sample
{
    static void Main()
    {
        int[] array = { 0, 1, 2, 3 };
        MakeAtLeast<int>(array, 2); // Sprememba originalne tabele v { 2, 2, 2, 3 }
        foreach (int i in array)
            Console.WriteLine(i); // Izpis rezultata.
        Console.ReadKey(true);
    }

    static void MakeAtLeast<T>(T[] list, T lowest) 
        where T : IComparable<T>
    {
        for (int i = 0; i < list.Length; i++)
            if (list[i].CompareTo(lowest) < 0)
                list[i] = lowest;
    }
}

Naslednji primer prikazuje definicijo in uporabo generičnega razreda. Pomembna lastnost generikov v .NET je, da so statični elementi instanciirani za vsak konkreten tip, ki se instanciira med izvajanjem programa:


    // Generičen razred
    public class GenTest<T>
    {
        // Statična spremenljivka, ki bo generirana za vsak tip:
        static CountedInstances OnePerType = new CountedInstances();

        // Podatkovno polje, ki je tipa, kot ga določa tipski parameter:
        private T mT;

        // Enostaven konstruktor:
        public GenTest(T pT)
        {
            mT = pT;
        }
    }

    // Razred:
    public class CountedInstances
    {
        // Statična spremenljivka, ki bo inkrementirana  za vsako instanco:
        public static int Counter;

        // Enostaven konstruktor:
        public CountedInstances()
        {
            // Inkrementacija števca med instanciacijo (tvorjenjem objekta tega razreda):
            CountedInstances.Counter++;
        }
    }

  // Vstopna točka:
  // Po končani izvedbi bo CountedInstances.Counter = 2
  GenTest<int> g1 = new GenTest<int>(1);
  GenTest<int> g11 = new GenTest<int>(11);
  GenTest<int> g111 = new GenTest<int>(111);
  GenTest<double> g2 = new GenTest<double>(1.0);

Sklici uredi