X++ datu mota konposatuak

Oharra

Komunitatearen interes taldeak Yammer-etik Microsoft Viva Engage-ra mugitu dira. Viva Engage komunitate batean sartzeko eta azken eztabaidetan parte hartzeko, bete Request access to Finance and Operations Viva Engage Community formularioa eta aukeratu sartu nahi duzun komunitatean.

Artikulu honetan X++-ko datu mota konposatuak azaltzen dira. X++-ko datu mota konposatuak matrizeak, edukiontziak, klaseak datu mota gisa, delegatuak datu mota gisa eta taulak datu mota gisa dira.

Matrizea

Array datu mota bera duten elementuen zerrenda duen aldagaia da. Array bateko elementuak osoko indizeak erabiliz sartzen dira. Adierazpen bereizi bat erabiltzen duzu matrize bateko elementu bakoitza hasieratzeko. Bilduma bat sortzeko edukiontzi-datu mota bat edo matrize-objektu bat erabiltzen duzunean, hainbat elementu hasiera ditzakezu instrukzio bakarra erabiliz. Lehenespenez, matrize bateko elementu guztiek matrizearen datu motaren balio lehenetsia dute. Hiru matrize mota daude: matrize dinamikoak, luzera finkoko matrizeak eta, zati batean, disko-matrizeetan.

  • Matrize dinamikoak : matrize hauek matrize huts baten bidez deklaratzen dira. Juramentua ; Zal[di baten bi]zitza /
  • Luzera finkoko matrizeak : matrize hauek deklarazioan zehaztutako elementu kopurua eduki dezakete. Luzera finkoko matrizeak matrize dinamikoak bezala deklaratzen dira, baina parentesi artean luzera aukera bat sartzen da.
  • Partzialki disko-matrizeetan - Matrize hauek matrize dinamiko edo luzera finkoko matrize gisa deklaratzen dira, memorian zenbat elementu gorde behar diren adierazten duen aukera gehigarri bat dutenak. Gainerako elementuak diskoan gordetzen dira eta automatikoki kargatzen dira erreferentzia egiten direnean.

X++-k dimentsio bakarreko matrizeak soilik onartzen ditu. Hala ere, array indize anitzen portaera imita dezakezu. (Informazio gehiago nahi izanez gero, ikus Array indize anitzak atala). Objektu eta tauletako aldagaiak matrize gisa deklara daitezke. Adibidez, funtzionalitate hau aplikazio estandarreko helbide-lerroetan erabiltzen da. Array bildumaren klase batek matrize batean objektuak gordetzeko aukera ematen dizu.

Array indizeak 1etik hasten dira. Lehenengo elementua [1] bezala aipatzen da, bigarrena [2] eta abar. Array elementu bat sartzeko honako sintaxia erabiltzen da: ArrayItemReference = ArrayVariable [ Index ]. Sintaxi honetan, ArrayVariable matrizearen identifikatzailea da, eta Index matrizearen elementuaren zenbakia. Indizea osoko adierazpen bat izan daiteke. Zero elementua [0] matrizea garbitzeko erabiltzen da. Matrize bateko 0 indizeari balio bat esleitzen bazaio, matrizeko elementu guztiak beren balio lehenetsera berrezarriko dira.

Matrize osoa beste bati esleitzea erreferentzia bidez egiten da.

Array adibideak

public void ArrayMethod()
{
    int myArray[10]; // Fixed-length array with 10 integers.
    myArray[4] = 1; // Accessing the 4th element in the array.
    myArray[0] = 0; // Resets all elements in intArray.

    // Dynamic array of integers.
    int intArray[];

    // Dynamic array of variables of type Datatype.
    //Datatype arrayVariable[];

    // Fixed-length arrays.
    boolean boolArray[100]; // Fixed-length array of booleans with 100 items.

    // Two examples of Partly On Disk Arrays.
    // Dynamic integer array with only 100 elements in memory.
    int arrayVariable [ ,100];
    // Fixed-length string array with 1000 elements, and only 200 in memory.
    str arrayVariable2 [1000,200];

    // A dynamic array of integers.
    int i[];
    // A fixed-length real array with 100 elements.
    real r[100];
    // A dynamic array of dates with only 10 elements in memory.
    date d[,10];
    // A fixed length array of NoYes variables with 100 elements and 10 in memory.
    NoYes ny[100,10];
}

Array indize anitz

Lengoaia batzuek, hala nola C++ eta C#, indize bat baino gehiago dituzten matrizeak deklaratzeko aukera ematen dute. Beste modu batera esanda, "matrizeen matrizeak" defini ditzakezu. X++-en, ezin duzu zuzenean array indize anitz sortu, dimentsio bakarreko matrizeak soilik onartzen direlako. Hala ere, indize anitz inplementa ditzakezu atal honetan deskribatutako metodoa erabiliz. Adibidez, bi dimentsio dituen matrize bat deklaratu nahi duzu, herrialde/eskualdearen arabera dimentsioz irabazitako zenbatekoa gordetzeko. 10 herrialde/eskualde eta hiru dimentsio daude. C++ eta C#-n, ondorengo matrizea adierazten duzu.

// This is C# or C++ code, not X++ code.
long earning[10, 3];

Hala ere, X++-k ez du adierazpen hau onartzen. Horren ordez, dimentsio bakarreko matrize bat defini dezakezu, non elementu kopurua dimentsio bakoitzeko elementuen biderkadura den. Hau da adibide bat.

public void MultipleArrayMethod()
{
    // Step 1: define a one-dimensional array with the number
    // of elements that is the product of the elements in each dimension.
    real earnings[10*3];

    // Step 2: to refer to a specific element, such as earnings[i,j], write the following:
    // declare i and j (maybe) and assign the value to something
    int i = 1;
    int j = 2;
    real element = earnings[(i-1)*3 + j];
}

// This can be written into a macro like this:
#localmacro.earningIndex
(%1-1)*3+%2
#endmacro

public void CallTheMacro()
{
    // Next, call the specific element within the macro like this:
    int i = 1;
    int j = 2;
    real element = earnings[#earningIndex(i,j)];

    // The previous scheme can be extended to any number of dimensions.
    // The element a[i1, i2, ..., ik] can be accessed by computing the
    // offset into an array containing (d1*d2*...*dk) elements.
    //(i1 - 1)*d2*d3*..*dk +
    //(i2 - 1)*d3*d4*...*dk + .... +
    //(ik-1 -1)*dk +
    //(ik-1)
}

Edukiontzia

Edukiontzi-objektua datu mota primitiboak edo datu mota konposatuak dituen elementuen zerrenda dinamikoa da. Edukiontzi bat erabilgarria da bezeroaren eta zerbitzariaren mailen artean hainbat balio mota pasatu behar dituzunean. Hala ere, begizta batean zerrenda bat behin eta berriz gehitzeko asmoa baduzu, edukiontzi bat ez da aukera ona. Edukiontziak egokienak dira edukiontziaren tamaina edo edukia gehiegi aldatzen ez duten prozesuetarako. Edukiontzi batek gehiegizko datuen gehikuntzak jasaten dituenean, sistemaren errendimendu orokorra murriztu egin daiteke, edukiontzien datuak behin eta berriz kopiatu behar direlako eta espazio berria behin eta berriz esleitu behar delako.

Edukiontzi bat ez da klase bat. Edukiontzi batek balio primitiboen edo bestelako edukiontzien sekuentzia ordenatua du. Edozein motaren malgutasuna dela eta, edukiontzi batek mota desberdinetako balioak elkarrekin gordetzeko modu ona eskaintzen du. Edukiontzi bat datu-basean gorde daiteke. Edukiontzia taula bati zutabe bat gehitzeko Aplikazioen esploratzailea erabiltzean hauta dezakezun zutabe motetako bat da. Edukiontzi batek matrize baten edo bildumen antz pixka bat du, hala nola List edo Stack klaseak. Hala ere, ezin duzu edukiontzi baten tamaina edo edukia aldatu edukiontzia sortu ondoren.

Edukiontzi bat aldatzen duten X++ instrukzioek barnean edukiontzi berri bat eraikitzen dute eta behar bezala kopiatzen dituzte balioak. Edukiontzi bat beste edukiontzi aldagai bati esleitzeak ere edukiontziaren kopia berri bat sortzen du. Eragiketa horiek guztiek eragina izan dezakete errendimenduan. Edukiontzi baterako sarbidea ematen duten funtzioetan ( adibidez, conPeek), edukiontzia 1ean oinarrituta, ez 0 oinarrituta. Indexazioa 1-ean oinarrituta matrizeetarako. Edukiontzi baten balio lehenetsia hutsik. Edukiontziak ez dauka baliorik. Edukiontziak erabiltzen dituzten adierazpen batzuek edukiontzi bat aldatzen dutela dirudi, baina sistemaren barruan, edukiontziak ez dira inoiz aldatzen. Horren ordez, jatorrizko edukiontziaren datuak komandoaren datuekin konbinatzen dira edukiontzi berri bat eraikitzeko. Edukiontzi berri bat sor dezakezu funtzio hauetako bat erabiliz: conDel, conIns edo conPoke.

Gainera, Global klaseak edukiontziak maneiatzeko metodo estatikoak ditu. Metodo horien artean daude con2ArraySource, con2Buf, con2List, con2Str, containerFromXmlNode, conView eta str2Con. Edukiontzi bat maneiatzeko berezko funtzio batzuk daude, hala nola conIns eta conPeek. X++ conPeek funtzioak edozein mota mota itzultzen du, beraz, errazagoa da edukiontzi bateko balioak irakurtzea balio bakoitzaren mota ezagutzen ez duzunean. Any mota X++ edozein balio motari esleitu ahal zaio, baldin eta balioa bihur badaiteke. Zure kodea errazago irakurtzen da datu moten bihurketa esplizituak saihesten dituenean. Beraz, esleitu edukiontzi bateko balioak edukiontzian jartzeko erabili zen datu mota berari. Ez diozu edukiontzirik edozein mota esleitu behar, sistemak bihurketa egokiak zehaztu ezin dituelako. Kasu horietan, ustekabeko portaera edo akatsak gerta daitezke.

Edukiontzia beste aukera batzuekin alderatzea

Edukiontzi motak beste eraikuntza batzuen antzekoa da, hala nola matrizeak eta bilduma klaseak, hala nola Zerrenda eta Pila. Edukiontzi baten eta Listaren arteko aldea da List klasearen instantzia bat aldagarria dela. Zerrenda objektu batek datuek kontsumitzen dutena baino leku gehiago esleitzen du. Ondoren, datuak gehitzen diren heinean, espazioa betetzen da. Portaera hau eraginkorragoa da elementu bat gehitzen den bakoitzean espazio gehiago esleitzea baino. Zerrenda baten eguneratzeak edukiontzi batean antzeko eragiketak baino azkarrago funtzionatzen du.

Zerrenda objektu bat eraikitzen duzunean, Zerrenda objektuak gorde dezakeen datu mota zehazten duzu. Murrizketa hau ez da malguagoa zerrenda batentzat edukiontzi batentzat baino. Hala ere, objektuak zerrenda batean gorde ditzakezu, eta edukiontzi batek balio motak soilik gorde ditzake. Edukiontzi baten eta matrize baten arteko aldea da matrize batek deklaratutako motako elementuak soilik eduki ditzakeela. Matrize bati memoria-lekua esleitu diezaiokezu eta geroago balioekin bete dezakezu. Adibidez, begizta batean balioak bete ditzakezu. Jarrera eraginkorra da eta ondo funtzionatzen du. Edukiontzi berri bat eraiki nahi duzunean, datu berriak erantsiz, eragilea += edo conIns funtzioa erabil ditzakezu. Operadorea += da alternatiba azkarrena. Erabili conIns funtzioa jatorrizko datuen azken indizearen aurretik datu berriak gehitu nahi dituzunean soilik.

Ezin dituzu objektuen erreferentziak edukiontzietan gorde. Konpilatzaileak objektu-erreferentzia bat edukiontzi batean gordetzeko saiakera bat detektatzen duenean, errore-mezu bat igorriko du. Edukiontziari gehitzen zaion elementuaren mota edozein mota bada, konpilatzaileak ezin du zehaztu balioa erreferentzia mota den ala ez. Kasu honetan, konpilatzaileak saiakera baimentzen du. Konpilatzaileak kodea oker gisa diagnostikatzen ez duen arren, errore bat botako da exekuzio garaian.

Edukiontzien adibideak

public void ContainerExample()
{
    // First, declare the variables you are using.
    container myContainer;
    container myContainer4;
    container myContainer5;
    // Three ways to declare a container.
    myContainer = [1];
    myContainer += [2];
    myContainer4 = myContainer5;

    // Declare a container.
    container cr3;

    // Assign a literal container to a container variable.
    cr3 = [22, "blue"];

    // Declare and assign a container.
    container cr2 = [1, "blue", true];

    // Mimic container modification (implicitly creates a copy).
    cr3 += [16, strMyColorString];
    cr3 = conIns(cr3, 1, 3.14);
    cr3 = conPoke(cr3, 2, "violet");

    // Assignment of a container (implicitly creates a copy).
    cr2 = cr3;

    // Read a value from the container.
    str  myStr = conPeek(cr2, 1);

    // One statement that does multiple assignments from a container.
    str myStr;
    int myInt;
    container cr4 = ["Hello", 22, 20\07\1988];
    [myStr, myInt] = cr4; // "Hello", 22

    // Example of applying the = operator to a container. The example
    // initializes myContainer2 and myContainer33.
    myContainer2 = [2, "apple"];

    // Next, you make a copy of myContainer33 and assign the copy to myContainer2.
    myContainer33 = [33, "grape"];
    myContainer2 = myContainer33;  // The container that myContainer2 had been holding is no longer available and cannot be recovered.
    // An example of building a new container by
    // assigning a new value to myContainer33 through the += operator.
    myContainer33 += [34, "banana"];
}

// Container example. In this example, variable2 and variable33 hold different containers.
static void JobC(Args _args)
{
    container variable2, variable33;
    variable2 += [98];
    variable33 = variable2;
    variable2 += [97];
}

// List class example. In this example, variable2 and variable33 refer to the same List object.
static void JobL(Args _args)
{
    List variable2,variable33;
    variable2 = new List(Types::Integer);
    variable2.addEnd(98);
    variable33 = variable2;
    variable2.addEnd(97);
}

// The automatic type conversion by anytype also applies to the special syntax for making multiple
// assignments from a container in one statement. This is shown in the following code example,
// which assigns a str to an int, and an int to a str.
static void JobContainerMultiAssignmentUsesAnytype(Args _args)
{
    container con2;
    int int4;
    str str7;
    con2 = ["11", 222];
    [int4, str7] = con2;
    info(strfmt("int4==11==(%1), str7==222==(%2)", int4, str7));
}

/***  Output:
Message (10:36:22 am)
int4==11==(11), str7==222==(222)
***/

static void UseQuery()
{
    // An example of how the compiler diagnoses attempts to store object in containers
    container c = [new Query()];   // This statement will cause the error message shown below.
    /*** Instance of type 'Query' cannot be added to a container. ***/

    // An example of a code that won't cause an error message, but will
    // cause an error message to be thrown at runtime.
    anytype a = new Query();
    container d = [a];
}

Datu mota gisa klaseak

Klase bat klasearen instantzien aldagaiak eta metodoak deskribatzen dituen motaren definizioa da. (Klase baten instantziak objektu gisa ere ezagutzen dira.) Klase bat objektuen definizioa baino ez da, eta objektu guztiak nuluak dira deklaratzen direnean. Application Explorer-en, Classes nodoaren azpiko aplikazio-klase bakoitza datu mota bat da. Mota horietako aldagaiak deklaratzen dituzu zure kodean. Klase bateko instantziak eraiki ditzakezu eta instantziak aldagaiei esleitu.

Klaseak iturburu-kodean sartu daitezke. Klase habiaratuak inprimakien barruan soilik daude erabilgarri ( adibidez, FormRun hedatzen duen klase bat), eta kontrolak, datu-iturburuak edo datu-eremuak irudikatzeko erabiltzen dira. Atributu-dekorazio batek, hala nola klase edo metodo bateko atributu-dekorazioak, atributu-izenaren atzizkia alde batera utz dezake, atzizkia Atributua bada. Beraz, X++-k [MyFavorite] baimentzen du [MyFavoriteAttribute] eskatu beharrean. Gainera, atributuak orain delegatuen eta metodoen kudeatzaileei aplikatzen zaizkie, kudeatzaileak helburu horietara mapatzeko.

AX 2012 eta aurreko bertsioetan, bezeroan edo zerbitzarian exekutatzeko metodo bat izendatu dezakezu. Hala ere, finantza eta eragiketa aplikazioetan, konpilatutako X++ kode guztia .NET Common Intermediate Language (CIL) gisa exekutatzen da zerbitzarian. Jada ez bezeroaren gunean edo nabigatzailean ebaluatzen den koderik. Beraz, bezeroaren eta zerbitzariaren gako-hitzak ez dira kontuan hartzen. Nahiz eta gako-hitz hauek ez duten konpilazio-errorerik eragiten erabiltzen badira, ez lirateke kode berrietan erabili behar.

Kideen aldagai pribatuak eta babestuak

Lehen, klase batean definitutako aldagai guztiak babestuta zeuden. Orain kideen aldagaien ikusgarritasuna esplizituki egin dezakezu gako-hitz pribatuak, babestuak eta publikoak gehituz. Aldatzaile hauen interpretazioa begi-bistakoa da eta metodoen semantikarekin bat dator:

  • private - Member aldagaia definituta dagoen klasean soilik erabil daiteke.
  • protected - Member aldagaia definituta dagoen klasean eta klase horretako azpiklase guztietan erabil daiteke.
  • public - Member aldagaia edozein lekutan erabil daiteke. Definituta dagoen klase hierarkiaren mugetatik kanpo ikus daiteke.

Lehenespenez, aldatzaile esplizitu batekin apainduta ez dauden aldagaiak babestuta daude oraindik. Hala ere, praktika egoki gisa, ikusgarritasuna esplizituki zehaztu beharko zenuke. Lehen deskribatu dugun bezala, kide aldagai bat publiko gisa definitzen denean, definituta dagoen klasetik kanpo sar daiteke. Kasu honetan, aldagaia ostatatzen duen objektua izendatzen duen kalifikatzaile bat zehaztu behar duzu. Kalifikatzailea zehazteko, erabili puntu-notazioa, metodo-deiekin egiten duzun bezala.

Ondorengo adibidean, field1 atzitzen da this kalifikatzaile esplizitua erabiliz. Kasu honetan, agian ez da ideia ona kide aldagai bat publiko egitea, ikuspegi horrek klasearen barne-funtzionamendua kontsumitzaileei erakusten baitie, eta, beraz, klasearen inplementazioaren eta kontsumitzaileen arteko menpekotasun handia sortzen duelako. Beti saiatu behar duzu kontratu baten mende egoten, ez inplementazio baten arabera.

public class AnotherClass3
{
    int field1;
    str field2;
    void new()
    {
        this.field1 = 1;   // Explicit object designated.
        field2 = "Banana";  // 'this' assumed, as usual.
    }
}

Eraikitzaile estatikoak eta eremu estatikoak

Eremu estatikoak gako-hitz estatikoa erabiliz deklaratzen diren eremuak dira. Kontzeptualki, eremu estatikoak klaseari aplikatzen zaizkio, ez klaseko instantziei. Eraikitzaile estatikoak klaseari dei estatikoak edo instantzia deiak egin aurretik exekutatuko direla bermatzen da. Eraikitzaile estatikoaren exekuzioa erabiltzailearen saioarekiko erlatiboa da. Inoiz ez diozu eraikitzaile estatikoari esplizituki deitu. Horren ordez, konpilatzaileak kodea sortuko du eraikitzaileari behin deitzen zaiola ziurtatzeko, klaseko beste edozein metodori deitu aurretik. Eraikitzaile estatikoa datu estatikoak hasieratzeko edo behin bakarrik egin behar den ekintza bat egiteko erabiltzen da. Ezin duzu parametrorik eman eraikitzaile estatikoarentzat, eta gako-hitz estatikoarekin markatu behar da.

// An example of how a singleton (call instance in the example below)
// can be created using the static constructor.
public class Singleton
{
    private static Singleton instance;
    private void new()
    {
    }
    static void TypeNew()    // This is the static constructor.
    {
        instance = new Singleton();
    }

    public static Singleton Instance()
    {
        return Singleton::instance;
    }
}

// The singleton ensures that only one instance of the class
// will be called, which is consumed by the following.
{
    // Your code here.
    Singleton i = Singleton::Instance();
}

Klase-elementuak Application Explorer-en

Application Explorer-eko klase nodo gehienen azpian, bi nodo berezi daude: classDeclaration nodo bat eta nodo berri bat. ClassDeclaration batek beti dauka X++ klaseko gako-hitza. Gako-hitz gehigarriak, hala nola hedapenak, sar daitezke klasea aldatzeko. Nodo honek kide aldagaien adierazpenak ere izan ditzake.

Hurrengo adibidean, m_priority eta m_rectangle aldagaiak klaseko kideak dira.

// An example of a classDeclaration.
public class YourDerivedClass extends YourBaseClass
{
    int m_priority;
    Rectangle m_rectangle;
    void new(int _length, int _width)
    {
        this.m_rectangle = new Rectangle(_length, _width);
    }
}

Eragile berri batek eragile berria klasearen instantzia bat sortzeko erabiltzen denean exekutatzen den logika du. Metodo berriaren logikak objektu bat eraiki dezake eta objektu hori classDeclaration-en deklaratzen den aldagai bati esleitu diezaioke. Klase bakoitzak metodo berri bakarra izan dezake. Hala ere, metodo berrian , askotan oinarrizko klasearen metodo berriari deitu behar diozu. Oinarrizko klasearen metodo berriari deitzeko, deitu super().

Ondorengo adibidean YourDerivedClass klasearen metodo berria erakusten da aurreko classDeclaration adibidean. Metodo berri honetan, kodeak Rectangle klasearen instantzia bat eraikitzen du. Instantzia m_rectangle aldagaiari esleitzen zaio. Adibide honetan erabiltzen den gako-hitz hau aukerakoa da, baina sartzen baduzu, IntelliSense lagungarriagoa izan daiteke.

// An example of the new method from the previous classDeclaration example.
void new(int _length, int _width)
{
    this.m_rectangle = new Rectangle(_length, _width);
}

Zabor-bilketa

Azkenean, exekuzio denboran, objektu gehienek jada ez dute haietara seinalatzen duen aldagairik. Sistemak objektu horiek eskaneatzen ditu eta memoriatik ezabatzen ditu. Memoria-espazioa beste erabilera batzuetarako erabilgarri bihurtzen da. Object klaseak finalize izeneko metodoa du. Hala ere, azken metodoa ez da suntsitzailea. Exekuzio-denborak ez dio inoiz finalize metodoari deitzen, nahiz eta objektu bat zabor gisa biltzen den.

Sistema-klaseak

Application Explorer-en, Sistemaren dokumentazio>klaseak atalean, nukleo-klaseen edo sistema-klaseen zerrenda. Sistemaren klaseak ez daude X++-n idatzita, eta ezin duzu haien iturburu-kodea ikusi. Ezin duzu sistema-klaserik gehitu. Sistema-klaseek metodo berri bat izan ohi dute, baina ez dute classDeclaration nodorik. Aplikazio klase bakoitzak Objektu sistemaren klasea inplizituki hedatzen du. Sistema-klase batzuk antzeko izena duen aplikazio-klase batek hedatzen ditu. Adibidez, xClassFactoryClassFactory-k zabaltzen du. Kasu horietan, ez zenuke sistema klasea erabili behar. Informazio gehiago nahi izanez gero, ikus "Aplikazio-klaseak ordezkatu sistema-klaseekin" Klaseak eta metodoak.

Luzapen-metodoak

Hedapen-metodoaren eginbideak xede-klase bati hedapen-metodoak gehitzeko aukera ematen dizu, metodoak luzapen-klase bereizi batean idatziz. Honako arau hauek aplikatzen dira:

  • Hedapen-klaseak estatikoa izan behar du.
  • Hedapen-klasearen izenak hamar karaktereko atzizkiarekin amaitu behar _Extension, hala ere, ez murrizketarik atzizkiaren aurretik dagoen izenaren zatian.
  • Hedapen klaseko hedapen metodo guztiak estatiko publiko gisa deklaratu behar dira.
  • Hedapen metodo bakoitzaren lehenengo parametroa luzapen metodoak hedatzen duen mota da. Hala ere, luzapen-metodoa deitzen denean, deitzaileak ez du ezer pasatu behar lehenengo parametrorako. Horren ordez, sistemak automatikoki pasatzen du lehenengo parametrorako beharrezko objektua.
  • Hedapen-metodo baten helburua klase, taula, ikuspegi edo mapa aplikazioaren objektu mota izan behar du.

Hedapen klase batek metodo estatiko pribatuak edo babestuak izan ditzake. Metodo hauek normalean inplementazioaren xehetasunetarako erabiltzen dira eta ez dira luzapen gisa agertzen. Hedapen metodoaren teknikak ez dio eragiten hedatzen duen klasearen iturburu-kodeari, beraz, klaseari gehikuntzak ez du gehiegizko geruzarik behar.

Helburuko klasearen bertsio-berritzeek ez dute inoiz lehendik dauden hedapen-metodoek eragiten. Helburuko klasearen bertsio-berritze batek zure hedapen-metodoaren izen bera duen metodo bat gehitzen badu, zure hedapen-metodoa ezin da gehiago iritsi helburuko klaseko objektuen bidez. Hedapen metodoaren teknikak puntuz mugatutako sintaxia bera erabiltzen du, ohiko instantzia metodoak deitzeko erabiltzen duzuna. Hedapen-metodoek helburuko klasearen artefaktu publiko guztiak sar ditzakete, baina ezin dute babestuta edo pribatua den ezer atzitu. Beraz, hedapen metodoak azukre sintaktiko mota gisa har daitezke. Helburu mota edozein dela ere, hedapen klase bat erabiltzen da motari hedapen metodoak gehitzeko. Adibidez, luzapen-taula bat ez da erabiltzen taula bati metodoak gehitzeko, eta ez luzapen-taula bat.

// An example of an extension class holding a few extension methods.
public static class AtlInventLocation_Extension
{
    public static InventLocation refillEnabled(
        InventLocation _warehouse,
        boolean _isRefillEnabled = true)
    {
        _warehouse.ReqRefill = _isRefillEnabled;
        return _warehouse;
    }

    public static InventLocation save(InventLocation _warehouse)
    {
        _warehouse.write();
        return _warehouse;
    }
}

Ordezkariak datu mota gisa

Ordezkari batek harpidetzen duten metodoak biltzen ditu. Ordezkariak harpidedun metodo guztiek partekatu behar duten parametro-sinadura zehazten du. Delegatuari deitzen zaionean, harpidedun bakoitzari deitzen dio. Ordezkari batek ez du inoiz baliorik itzultzen, eta ezin du balio lehenetsia izan. Hasieran, ordezkari guztiek ez dute harpidetutako metodorik. Ez mugarik delegatu batek deklaratu ditzakeen parametro kopuruan, eta ez parametro horien motari buruzko mugarik. Delegatuaren organoa hutsik beti, delegatuaren helburu bakarra harpidedunek bete behar duten kontratua definitzea delako. Delegatu bat ez da klase batean definitu behar. Ordezkariak taula batean, inprimakian edo kontsulta batean ere defini daitezke.

Ordezkarien adibideak

abstract class VarDatClass
{

    void new(utcdatetime _dateTime, str _changeDescription)
    {
        // An example of subscribing a delegate.
        this.notifyChanged += eventhandler(this.InfologChanges);
        this.notifyChanged += eventhandler(this.SaveInDatabase);
        
        notifyChange(_dateTime, _changeDescription);
    }

    void notifyChange(utcdatetime _dateTime, str _changeDescription)
    {
        // An example of calling a delegate.
        this.notifyChanged(_dateTime, _changeDescription);
    }
    
    // delegate method examples
    // An example of declaring a delegate.
    delegate void notifyChanged(utcdatetime _dateTime, str _changeDescription)
    {
    }

    // method that is to be subscribed.
    public static void InfologChanges(utcDateTime _dateTime, str _changeDescription)
    {
        info("A notification has occurred calling static handler:" +
            DateTimeUtil::toStr(_dateTime) +
            " Message:" +
            _changeDescription);
    }
    
    // method that is to be subscribed.
    public static void SaveInDatabase(utcDateTime _dateTime, str _changeDescription)
    {
       // save changes in database.
    }
    
    
}

Taulak datu mota gisa

Taula guztiak klase definizio gisa tratatu daitezke. Taulako aldagai bat taularen (klase) definizioaren instantzia (objektua) gisa har daiteke. Taulako aldagai bateko eremu bakoitzeko, balio lehenetsia hutsik. Eremuak zuzendu eta tauletan metodoak sor ditzakezu. Metodoak taulako instantzietan erabil daitezke. Tauletako erregistroak manipulatzeko (hau da, irakurri, eguneratu, txertatu eta ezabatu), gutxienez erregistroa fokuan eduki dezakeen taula-aldagai bat deklaratu behar duzu. Praktika egoki gisa, taularen izena erabili beharko zenuke aldagaiaren izen gisa, baina hasierako letra minuskulak erabili. Hona hemen taulen eta objektuen arteko desberdintasun garrantzitsu batzuk:

  • Ezin duzu taulako aldagaiei lekurik esleitu. Esleipena inplizituki egiten da.
  • Taulako aldagaietako eremuak publikoak dira. Edonon erreferentzia ditzakezu.
  • Taulako aldagaietako eremuak adierazpenak erabiliz erreferentzia daitezke.

Ez bihurketa automatikorik, baina Common gisa deklaratutako taulako aldagaiek edozein taulako datuak eduki ditzakete.

Taulako aldagaien esparrua

Alderdi gehienetan, taulako aldagaiak objektutzat har daitezke, baina objektuak ez bezala, ez dira esplizituki esleitzen. Aldagaien deklarazioa baino ez da behar. Taula guztiak bateragarriak dira Common taularekin, objektu guztiak Object klasearekin bateragarriak diren bezala. Taulako aldagaiak buffer arrunt gisa deklaratzen dira eta edozein taulako datuak gordetzeko erabil daitezke. Ezin dira taula-aldagairik ez duten taulak atzitu. Taulako aldagaiak eta objektuak deklaratzeko printzipioak berdinak dira, espazioaren esleipenari dagokionez izan ezik.

Taulen adibideak

Sintaxiak erregistroetako eremuak erreferentzia egiteko aukera ugari eskaintzen ditu. Adibidez, taula izena erabil dezakezu . ( FieldId) sintaxia.

Ondorengo adibidean Bezeroaren taulako uneko erregistroko eremuen edukia inprimatzen da.

// Declares and allocates space for one CustTable record.
public void myMethod()
{
    CustomerTable custTable;
}

// An example of referencing table variables.
public void printAccountNo()
{
    CustomerTable custTable;
    print custTable.AccountNo;  // Prints the field reference.
}

Ondorengo adibidean fieldCnt eta fieldCnt2Id metodoak erabiltzen dira. fieldCnt metodoak taula bateko eremu kopurua zenbatzen du, eta fieldCnt2Id-ek, berriz, eremu-zenbaki baten IDa itzultzen du. Adibidez, fieldCnt2Id metodoa erabil dezakezu taula bateko 6 zenbakiko eremuak 54 IDa duela jakiteko. Bihurketa hori beharrezkoa da, ez baitago bermatzen taula bateko eremuen IDak segidakoak direnik.

// An example of the various possibilities for referencing fields in records.
public void printCust()
{
    int i, n, k;
    CustomerTable custTable;
    DictTable dictTable;
    dictTable = new DictTable(custTable.TableId);
    n = dictTable.fieldCnt();
    print "Number of fields in table: ", n;
    for(i=1; i<=n; i++)
    {
        k = dictTable.fieldCnt2Id(i);
        print "The ", dictTable.fieldName(k),
        " field with Id=",k, " contains '",
        custTable.(k), "'";
    }
}