X++ en C# vergelijking

In dit artikel worden de syntaxis en programmering van X++ en C# met elkaar vergeleken.

X++, C# Vergelijking: Hallo wereld

In deze sectie wordt het eenvoudigste X++ programma vergeleken met zijn tegenhanger in C#.

X++ naar C# vergelijkingen

In de volgende secties worden enkele basisovereenkomsten en verschillen tussen X++ en C# beschreven.

Similarities

De volgende X++-functies zijn hetzelfde voor C#:

  • Opmerkingen met één regel (//) en meerdere regels (/* */).
  • == (gelijke) operator om te bepalen of twee waarden gelijk zijn.
  • != (niet gelijk aan) operator om te bepalen of twee waarden niet equivalent zijn.
  • + (plusteken) operator voor aaneenschakeling van tekenreeksen.

Differences

In de volgende tabel worden X++-functies weergegeven die verschillen in C#.

Feature X++ C# Comments
if en else voorwaardelijke verklaringen De if instructie accepteert elk type expressie dat automatisch kan worden geconverteerd naar een Booleaans. Veelvoorkomende voorbeelden zijn an int waarvoor 0 onwaar betekent, of een object waarvoor null onwaar betekent. De if verklaring vereist een Booleaanse uitdrukking. De syntaxisstructuur met betrekking tot accolades en haakjes is precies hetzelfde tussen X++ en C#.
Literal string Een letterlijke tekenreeks kan op een van de volgende manieren worden gescheiden:
  • Een paar dubbele aanhalingstekens (") tekens.
  • Een paar tekens tussen enkele aanhalingstekens (').
Een letterlijke tekenreeks moet worden gescheiden door een paar dubbele aanhalingstekens ('). Voor X++ worden de dubbele aanhalingstekens meestal gebruikt om tekenreeksen af te bakenen. Het is echter handig om een tekenreeks te scheiden met enkele aanhalingstekens wanneer uw tekenreeks een dubbel aanhalingsteken moet bevatten.
verkolen type Er is geen a char of een tekentype in X++. Je kunt een str van lengte één declareren, maar het is nog steeds een string:
str 1 myString = "a";
Er is een char in C#. U kunt a char niet als parameter doorgeven aan een methode die een string parameter invoert, hoewel u de char parameter eerst expliciet kunt converteren naar een string. Zie Primitieve gegevenstypen voor meer informatie over X++-gegevenstypen.
Uitvoer van berichten X++ bezorgt berichten aan de gebruiker in het Infolog-venster. Veelgebruikte methoden zijn onder meer:
  • De gedrukte verklaring:
  • Statische methoden op de Global klas:
    • Global::info
    • Global::warning
    • Global::error
Voor een opdrachtregelprogramma kunnen berichten worden afgeleverd bij de console. Veelgebruikte methoden zijn onder meer:
  • Console.Out.WriteLine
  • Console.Error.WriteLine

X++ en C# voorbeelden

Deze sectie bevat twee eenvoudige codevoorbeelden. Het ene voorbeeld is geschreven in X++ en het andere is in C#. Beide monsters bereiken hetzelfde resultaat. De volgende X++-functies worden gedemonstreerd:

  • // Commentaar met één regel
  • /\* \*/ Commentaar met meerdere regels
  • if verklaring
  • == bediener
  • != bediener
  • + operator om tekenreeksen samen te voegen
  • Global::info voor berichtuitvoer, met en zonder het voorvoegsel Global::
  • Global::fout voor berichtuitvoer
  • Het gebruik van enkele en dubbele aanhalingstekens ("en ") als scheidingstekens voor tekenreeksen.

Note

Het is het beste om dubbele aanhalingstekens te gebruiken voor elke tekenreeks die aan de gebruiker kan worden getoond.

X++ Sample

Dit X++-codevoorbeeld heeft de vorm van een taak. Er is een knooppunt met de naam Jobs in de Application Object Tree (AOT). Dit voorbeeld kan worden toegevoegd onder het knooppunt Taken en vervolgens kan de taak worden uitgevoerd.

static void JobRs001a_HelloWorld(Args _args)
{
    if (1 == 1) 
    {
        // These two info() calls are identical to the X++ compiler.
        // The second form is the one typically used in X++.
        Global::info("Hello World, 1.");
        info('Hello World, 2.');
    }
    if (1 != 1)
    {
        error("This message will not appear.");
    }
    else
    {
        // These two methods are also from the Global class.
        // The + operator concatenates two strings.
        warning("This is like info, but is for warnings, 3.");
        error("This is like info, but is for errors, 4.");
    }
}
Output

Hier is de uitvoer van het Infolog-venster: Bericht (09:49:48) Hallo Wereld, 1. Hallo Wereld, 2. Dit is als info, maar is voor waarschuwingen, 3. Dit is als info, maar is voor fouten, 4.

C# Sample

Het volgende C#-programma is een herschrijving van het vorige X++-programma.

using System;
class Pgm_CSharp
{
    static void Main( string[] args )
    {
        new Pgm_CSharp().Rs001a_CSharp_HelloWorld();
    }
    void Rs001a_CSharp_HelloWorld()
    {
        if (1 == 1) 
        {
            Console .Out .WriteLine("Hello World, Explicit .Out , 1.");
            Console .WriteLine("Hello World, Implicit default to .Out , 2.");
        }
        if (1 != 1)
        {
            Console .Error .WriteLine("This message will not appear.");
        }
        else
        {
            Console .Error .WriteLine(".Error is like .Out, but can be for warnings, 3.");
            Console .Error .WriteLine(".Error is like .Out, but is for errors, 4.");
        }
    }
}
Output

Hier is de daadwerkelijke uitvoer naar de C#-console:

Hello World, Explicit .Out, 1. 
Hello World, Implicit default to .Out, 2. 
.Error is like .Out, but can be for warnings, 3. 
.Error is like .Out, but is for errors, 4.

X++, C# Vergelijking: Loops

In deze sectie worden de loop-functies tussen X++ en C# vergeleken.

Similarities

De volgende functies zijn hetzelfde in X++ en C#:

  • Declaraties voor variabelen van het gegevenstype int primitive. Declaraties voor andere primitieve typen zijn bijna hetzelfde, maar de typen kunnen verschillende namen hebben.
  • terwijl verklaring voor lussen.
  • Break-statement om een lus te verlaten.
  • Ga door met de verklaring om naar de top van een lus te springen.
  • <= (kleiner dan of gelijk) vergelijkingsoperator.

Differences

In de volgende tabel worden X++-functies weergegeven die verschillen in C#.

Features X++ C# Comments
De for verklaring. De for-verklaring is beschikbaar voor loops. De C# for instructie is iets anders dan for in X++. In C# kun je het teller gehele getal declareren in het for statement. Maar in X++ moet de teller buiten de for verklaring worden gedeclareerd.
++ Verhoging operator. Een ++ increment operator is beschikbaar in X++. Maar een int-variabele die is versierd met ++ kan alleen worden gebruikt als een statement, niet als een expressie. De volgende regels X++-code worden bijvoorbeeld niet gecompileerd:
int age=42;
print age++;
De volgende regels X++-code zouden echter worden gecompileerd:
int age=42;
age++; print age;
De operator C#++ is flexibeler dan in X++. De volgende regels code zijn in beide talen hetzelfde:
  • ++ myInteger;
  • myInteger++;
Maar de volgende regels code hebben een ander effect dan ze zijn alleen geldig in C#:
  • uwInt = ++mijnInt;
  • yourInt = mijnInt++;
modulo operator. In X++ is de modulo-operator mod. In C# wordt de modulo-operator %. De symbolen voor de modulo-operator zijn verschillend, maar hun gedrag is in beide talen hetzelfde.
Een consoleprogramma dat al is gestart, tijdelijk opschorten. De pause verklaring. In C# kan een opdrachtregelprogramma worden onderbroken door de volgende regel code:
Console.In.Read();
In X++ ga je verder door op een OK knop te klikken in een modaal dialoogvenster. In C# ga je verder door op een willekeurig toetsenbord op het toetsenbord te drukken.
Geef een bericht weer. In X++ wordt een print bericht weergegeven in het afdrukvenster. In C# kan een bericht op de console worden weergegeven met de volgende regel code:
Console.WriteLine();
De functie X++ print wordt alleen gebruikt wanneer u test. Een X++ programma dat bijna altijd print ergens later in de code gebruiktpause. Gebruik voor de productie van X++-code de Global::info-methode in plaats van print. De strfmt functie wordt vaak gebruikt in combinatie met info. Er is geen reden om pause na info.
Maak geluid. De piepfunctie maakt een geluid dat je hoort. In C# wordt een geluid dat u kunt horen, uitgegeven door de volgende coderegel:
Console.Beep();
De uitspraken leveren elk een korte toon op.

De X++-codesamples voor loops gebruiken de print functie om resultaten weer te geven. In X++ kun je de print instructie gebruiken om elk primitief gegevenstype weer te geven zonder dat je functies hoeft aan te roepen die het eerst naar een string converteren. Dit is print handig in snelle testsituaties. Over het algemeen wordt de methode Global::info vaker gebruikt dan print. De info methode kan alleen tekenreeksen weergeven. Daarom wordt de strfmt-functie vaak gebruikt in combinatie met info. Een beperking hiervan print is dat u de inhoud van het afdrukvenster niet naar het klembord kunt kopiëren (zoals met Ctrl+C). Global::info schrijft naar het Infolog-venster dat wel ondersteuning biedt voor kopiëren naar het klembord.

Voorbeeld 1: De while-lus

Het while-trefwoord ondersteunt looping in zowel X++ als C#.

X++ Voorbeeld van terwijl

static void JobRs002a_LoopsWhile(Args _args)
{
    int nLoops = 1;
    while (nLoops <= 88)
    {
        print nLoops;
        pause;
        // The X++ modulo operator is mod.
        if ((nLoops mod 4) == 0)
        {
            break;
        }
        ++ nLoops;
    }
    beep(); // Function.
    pause; // X++ keyword.
} 
Output

De uitvoer in het X++ Print-venster is als volgt:

1
2
3
4

C# Voorbeeld van while

using System;
public class Pgm_CSharp
{
    static void Main( string[] args )
    {
        new Pgm_CSharp().WhileLoops();
    }

    void WhileLoops()
    {
        int nLoops = 1;
        while (nLoops <= 88)
        {
            Console.Out.WriteLine(nLoops.ToString());
            Console.Out.WriteLine("(Press any key to resume.)");
            // Paused until user presses a key.
            Console.In.Read();
            if ((nLoops % 4) == 0) {
                break;
            }
            ++ nLoops;
        }
        Console.Beep();
        Console.In.Read();
    }
}
Output

De console-uitvoer van het C#-programma is als volgt:

1
(Press any key to resume.)
2
(Press any key to resume.)
3
(Press any key to resume.)
4
(Press any key to resume.)

Voorbeeld 2: De for lus

Het voor trefwoord ondersteunt looping in zowel X++ als C#.

X++ Voorbeeld van voor

In X++ kan de tellervariabele niet worden gedeclareerd als onderdeel van de for instructie.

static void JobRs002a_LoopsWhileFor(Args _args)
{
    int ii; // The counter.
    for (ii=1; ii < 5; ii++)
    {
        print ii;
        pause;
        // You must click the OK button to proceed beyond a pause statement.
        // ii is always less than 99.
        if (ii < 99)
        {
            continue;
        }
        print "This message never appears.";
    }
    pause;
}
Output

De uitvoer in het X++ Print-venster is als volgt:

1
2
3
4

C# Voorbeeld van voor

using System;
public class Pgm_CSharp
{
    static void Main( string[] args )
    {
        new Pgm_CSharp().ForLoops();
    }
    void ForLoops()
    {
        int nLoops = 1, ii;
        for (ii = 1; ii < 5; ii++)
        {
            Console.Out.WriteLine(ii.ToString());
            Console.Out.WriteLine("(Press any key to resume.)");
            Console.In.Read();
            if (ii < 99)
            {
                continue;
            }
            Console.Out.WriteLine("This message never appears.");
        }
        Console.Out.WriteLine("(Press any key to resume.)");
        Console.In.Read();
    }
}
Output

De console-uitvoer van het C#-programma is als volgt:

1
(Press any key to resume.)
2
(Press any key to resume.)
3
(Press any key to resume.)
4
(Press any key to resume.)
(Press any key to resume.)

X++, C# Vergelijking: Switch

In zowel X++ als C# omvat de switch-instructie de trefwoorden hoofdletters, breuk en standaard. De volgende tabel geeft een overzicht van de verschillen in de switch-instructie tussen X++ en C#.

Feature X++ C# Comments
break; aan het einde van elk caseblok In X++, wanneer een case-blok overeenkomt met de expressiewaarde op de switch-clausule , worden alle andere case - en standaardblokken uitgevoerd totdat een break; instructie is bereikt. Er is nooit break; een statement nodig in een X++ switch statement, maar break; statements zijn in bijna alle praktijksituaties wel belangrijk. In C# is een break; instructie altijd nodig na de instructies in een hoofdletter - of standaardblok . Als een case-clausule geen verklaringen heeft tussen zichzelf en de volgende case-clausule , is een break; verklaring niet vereist tussen de twee case-clausules . We raden af om de break; instructie na een case-block weg te laten, omdat dit de volgende programmeur die de code bewerkt in verwarring kan brengen.
break;aan het einde van het standaardblok In X++ is er geen effect van het toevoegen van een break; statement aan het einde van het standaardblok . In C# vereist de compiler een break; instructie aan het einde van het standaardblok . Zie Switch-instructies voor meer informatie.
Alleen constante waarden op een caseblok In X++ kun je een letterlijke waarde of een variabele op een hoofdletterblok opgeven. U kunt bijvoorbeeld het hoofdlettergebruik myInteger: schrijven. In C# moet u precies één letterlijke waarde opgeven voor elk hoofdletterblok en er zijn geen variabelen toegestaan. No comments.
Meerdere waarden op één caseblok In X++ kun je meerdere waarden opgeven voor elk caseblok. De waarden moeten worden gescheiden door een komma. U kunt bijvoorbeeld schrijven case 4,5,myInteger:. In C# moet u precies één waarde opgeven voor elk hoofdletterblok . In X++ is het beter om meerdere waarden op één caseblok te schrijven dan de instructie aan het einde van een of meer caseblokken weg te laten break; .

Codevoorbeelden voor switch

In de volgende secties worden vergelijkbare switch-instructies in X++ en C# weergegeven.

X++ schakelaar Voorbeeld

Het voorbeeld van de X++-switch laat het volgende zien:

  • case iTemp:en om aan te tonen dat case-expressies niet beperkt zijn tot constantencase (93-90):, zoals in C#.
  • //break; om aan te tonen dat break; statements niet nodig zijn in X++, hoewel ze bijna altijd wenselijk zijn.
  • case 2, (93-90), 5: om aan te geven dat meerdere expressies kunnen worden weergegeven op één hoofdletterclausule in X++.
static void GXppSwitchJob21(Args _args)  // X++ job in AOT &gt; Jobs.
{
    int iEnum = 3;
    int iTemp = 6;
    switch (iEnum)
    {
        case 1:
        case iTemp:  // 6
            info(strFmt("iEnum is one of these values: 1,6: %1", iEnum));
            break;
        case 2, (93-90), str2Int("5"):  // Equivalent to three 'case' clauses stacked, valid in X++.
            //case 2:
            //case (93-90):  // Value after each 'case' can be a constant, variable, or expression; in X++.
            //case str2Int("5"):
            info(strFmt("iEnum is one of these values: 2,3,5: %1", iEnum));
            //break;  // Not required in X++, but usually wanted.
        case 4:
            info(strFmt("iEnum is one of these values: 4: %1", iEnum));
            break;
        default:
            info(strFmt("iEnum is an unforeseen value: %1", iEnum));
            break;
            // None of these 'break' occurrences in this example are required for X++ compiler.
    }
    return;
}

/*** Copied from the Infolog:
Message (02:32:08 pm)
iEnum is one of these values: 2,3,5: 3
iEnum is one of these values: 4: 3
***

C# schakelaar Voorbeeld

Het voorbeeld van de C#-switch laat het volgende zien:

  • Geval 1: Bevat een opmerking waarin wordt uitgelegd dat alleen constante uitdrukkingen kunnen worden gegeven op een hoofdletterclausule .
  • break; statements komen voor na de laatste instructie in elk caseblok dat statements bevat, zoals vereist door C#.
using System;
namespace CSharpSwitch2
{
    class Program
    {
        static void Main(string[] args)  // C#
        {
            int iEnum = 3;
            switch (iEnum)
            {
                case 1:  // Value after each 'case' must be a constant.
                case 6:
                    Console.WriteLine("iEnum is one of these values: 1,6: " + iEnum.ToString());
                    break;
                //case 2,3,5:  // In C# this syntax is invalid, and multiple 'case' clauses are needed.
                case 2:
                case 3:
                case 5:
                    Console.WriteLine("iEnum is one of these values: 2,3,5: " + iEnum.ToString());
                    break;
                case 4:
                    Console.WriteLine("iEnum is one of these values: 4: " + iEnum.ToString());
                    break;
                default:
                    Console.WriteLine("iEnum is an unforeseen value: " + iEnum.ToString());
                    break;
                // All 'break' occurrences in this example are required for C# compiler.
            }
          return;
        }
    }
}
/*** Output copied from the console:
>> CSharpSwitch2.exe
iEnum is one of these values: 2,3,5: 3
>>
***/

X++, C# vergelijking: tekenreekshoofdletters en scheidingstekens

In deze sectie wordt de behandeling van snaren met gemengde behuizing in X++ en C# vergeleken. Het legt ook de tekenreeksscheidingstekens uit die beschikbaar zijn in X++.

Similarities

De volgende X++-functies zijn hetzelfde als in C#:

  • De backslash (\) is de escape-operator voor tekenreeksscheidingstekens.
  • Het apenstaartje (@) heft het escape-effect van de backslash op wanneer het apenstaartje direct voor het open aanhalingsteken van een tekenreeks wordt geschreven.
  • Het plusteken (+) is de operator voor aaneenschakeling van tekenreeksen.

Differences

X++-functies die verschillen in C# worden weergegeven in de volgende tabel.

Feature X++ C# Comments
==Vergelijkingsoperator Ongevoelig: de == operator is ongevoelig voor verschillen in de snaarbehuizing. In C# is de == operator gevoelig voor verschillen in stringbehuizing. In X++ kun je de strCmp functie gebruiken voor hoofdlettergevoelige vergelijkingen tussen strings.
String delimiters In X++ kunt u het enkele (') of dubbele (") aanhalingsteken gebruiken als tekenreeksscheidingsteken.

Notitie: Meestal is het het beste om dubbele aanhalingstekens te gebruiken voor tekenreeksen die aan de gebruiker kunnen worden getoond. Het is echter handig om een tekenreeks af te bakenen met enkele aanhalingstekens wanneer een dubbel aanhalingsteken een van de tekens in de tekenreeks is.

In C# moet u het dubbele aanhalingsteken gebruiken als scheidingsteken voor de tekenreeks. Dit verwijst naar het type System.String. In X++ en C# heb je de mogelijkheid om een scheidingsteken in een letterlijke tekenreeks in te sluiten en deze te escapen met .
In X++ heb je ook het alternatief om enkele aanhalingstekens in te sluiten in een string die wordt begrensd door dubbele aanhalingstekens (of omgekeerd), zonder dat je de escape hoeft te gebruiken.
Character delimiters X++ heeft een tekenreeksgegevenstype (str), maar geen tekentype. In C# moet u het enkele aanhalingsteken gebruiken als scheidingsteken. Dit verwijst naar het type System.Char. In het .NET Framework is een System.String van lengte een ander gegevenstype dan een System.Char teken.

Voorbeeld 1: Hoofdlettergevoeligheid van de operator ==

De == operatoren en != zijn hoofdlettergevoelig in X++, maar zijn hoofdlettergevoelig in C#, zoals wordt geïllustreerd door het volgende voorbeeld.

X++ C# Comments
"HELLO" == "hello"
Waar in X++.
"HELLO" == "hello"
Onwaar in C#.
Verschillende hoofdlettervergelijkingen tussen X++ en C#.

Voorbeeld 2: De aaneenschakelingsoperator + tekenreeks

De operatoren + en += worden gebruikt om tekenreeksen in zowel X++ als C# samen te voegen, zoals wordt weergegeven in de voorbeelden in de volgende tabel.

X++ C# Comments
myString1 = "Hello" + " world";
Resultaat is gelijkheid:
myString1 == "Hello world"
(Zelfde als voor X++.) In zowel X++ als C# is het gedrag van de operator + afhankelijk van het gegevenstype van de operanden. De operator voegt tekenreeksen samen of voegt getallen toe.
mystring2 = "Hello";
myString2 += " world";
Resultaat is gelijkheid: myString2 == "Hello world"
(Zelfde als voor X++.) In zowel X++ als C# zijn de volgende statements equivalent:
a = a + b;
a += b;

Voorbeeld 3: Tekenreeksscheidingstekens insluiten en escapen

Enkele of dubbele aanhalingstekens kunnen worden gebruikt om tekenreeksen in X++ af te bakenen. Het escape-teken (\) kan worden gebruikt om scheidingstekens in een tekenreeks in te sluiten. Deze worden geïllustreerd in de volgende tabel.

X++ C# Comments
myString1 = "They said \"yes\".";
Result:
They said "yes".
(Zelfde als voor X++.) Met het escape-teken kunt u tekenreeksscheidingstekens in tekenreeksen insluiten.
myString2 = 'They said "yes".';
Result:
They said "yes".
De syntaxis C# staat niet toe dat enkele aanhalingstekens worden gebruikt om tekenreeksen af te bakenen. Voor tekenreeksen die door de gebruiker kunnen worden gezien, wordt het als een aanbevolen procedure beschouwd om het escape-teken te gebruiken in plaats van de enkele aanhalingstekens zoals in het voorbeeld.
myString3 = "They said 'yes'.";
Result:
They said 'yes'.
(Zelfde als voor X++.) In X++ worden de enkele aanhalingstekens niet behandeld als scheidingstekens, tenzij de tekenreeks begint met één scheidingsteken tussen aanhalingstekens. In C# heeft het enkele aanhalingsteken geen speciale betekenis voor tekenreeksen en kan het niet worden gebruikt om tekenreeksen af te bakenen. In C# is het enkele aanhalingsteken het vereiste scheidingsteken voor letterlijke letters van het type System.Char. X++ heeft geen tekengegevenstype.
str myString4 = 'C';
Hier is het enkele citaat een tekenreeksscheidingsteken.
char myChar4 = 'C';
Hier is het enkele aanhalingsteken een System.Char scheidingsteken, geen System.String scheidingsteken.
X++ heeft geen gegevenstype dat overeenkomt met System.Char in het .NET Framework. Een X++-tekenreeks die beperkt is tot een lengte van één is nog steeds een tekenreeks, geen tekengegevenstype.

Voorbeeld 4: Eén ontsnappingspersonage

Voorbeelden die het enkele escape-teken in de invoer of de uitvoer illustreren, worden weergegeven in de volgende tabel.

X++ C# Comments
myString1 = "Red\ shoe";
Result:
Red shoe
Een letterlijke tekenreeks in C# kan niet de reeks van twee tekens bevatten van escape gevolgd door een spatie, zoals "\ ". Er treedt een compilerfout op. Wanneer de X++ compiler de reeks van twee tekens van "\ " tegenkomt, wordt het enkele escape-teken verwijderd.
myString2 = "Red\\ shoe";
Result:
Red\ shoe
(Zelfde als voor X++.) In een paar ontsnappingskarakters ontkent de eerste de speciale betekenis van de tweede.

Vergelijking: Array-syntaxis

Er zijn overeenkomsten en verschillen in de functies en syntaxis voor arrays in X++ versus C#.

Similarities

Over het algemeen is er veel overeenkomst in de syntaxis en behandeling van arrays in X++ en C#. Er zijn echter veel verschillen.

Differences

De volgende tabel bevat gebieden in de syntaxis [] voor matrices die verschillend zijn voor X++ en C#.

Category X++ C# Comments
Declaration Een matrix wordt gedeclareerd met vierkante haken toegevoegd aan de naam van de variabele. Een matrix wordt gedeclareerd met vierkante haken die aan het gegevenstype worden toegevoegd. int myInts[]; // X++

Notitie: Een X++-array kan geen parameter zijn in een methode.

int[] myInts; // C#

Declaration De matrixsyntaxis ondersteunt alleen primitieve gegevenstypen, zoals int en str. De syntaxis biedt geen ondersteuning voor klassen of tabellen. De matrixsyntaxis ondersteunt primitieve gegevenstypen en -klassen. In X++ kunt u de Array Array gebruiken voor een array van objecten.
Declaration X++ is beperkt tot matrices met één dimensie (myStrings[8]). C# voegt ondersteuning toe voor multidimensionale arrays (myStrings[8,3]) en voor gekartelde arrays (myStrings[8][3]). In X++ kun je geen array van arrays hebben. Er is echter een geavanceerde syntaxis voor het beperken van de hoeveelheid actief geheugen die een grote array kan verbruiken, die eruitziet als de multidimensionale syntaxis in C#: int intArray[1024,16];. Zie Best Practice Performance Optimizations: Arrays verwisselen naar schijf voor meer informatie.
Declaration In X++ is een array een speciale constructie, maar het is geen object. In C# zijn alle arrays objecten, ongeacht de syntaxisvariaties. X++ heeft wel een Array-klasse, maar het onderliggende mechanisme verschilt van arrays die zijn gemaakt met behulp van de [] syntaxis. In C# gebruiken alle arrays hetzelfde onderliggende mechanisme, ongeacht of de syntaxis van de System.Array klasse in uw code wordt gebruikt.
Length In X++ wordt de lengte van een matrix met statische grootte bepaald in de declaratiesyntaxis. In C# wordt de grootte van een matrix bepaald wanneer het matrixobject wordt geconstrueerd. Wanneer u de syntaxis van de [] aangifte in X++ gebruikt, hoeft u zich niet meer voor te bereiden voordat u waarden aan de matrix toewijst.
In C# moet u de array declareren en vervolgens construeren voordat u deze toewijst.
Length Een X++-array kan een dynamische lengte hebben die kan worden vergroot, zelfs nadat de populatie is begonnen. Dit is alleen van toepassing wanneer de array wordt gedeclareerd zonder een nummer in de []. De prestaties kunnen worden vertraagd als de lengte van de dynamische array vele malen wordt vergroot. In C# kan de lengte van een matrix niet worden gewijzigd nadat de lengte is ingesteld. In het volgende fragment van X++-code is alleen de myInts matrix dynamisch en kan deze in grootte toenemen.
int myInts[];
int myBools[5];
myInts[2] = 12;
myInts[3] = 13;
myBools[6] = 26; //Error
Length U kunt de lengte van sommige matrices krijgen met behulp van de dimOf functie. C#-matrices zijn objecten die een Length eigenschap hebben. No comments.
Indexing Array-indexering is gebaseerd op 1. Array-indexering is gebaseerd op 0. mtIntArray[0] zou een fout veroorzaken in X++.
Constant In X++ kan een constante waarde het beste worden bereikt door gebruik te maken van de #define precompiler-directive. In C# kun je je variabele declaratie versieren met het trefwoord const, om een constante waarde te bereiken. X++ heeft geen const keyword. C# kan geen waarden toewijzen aan variabelen die zijn gemaakt door de precompiler-instructie van #define.

X++ en C# voorbeelden

In de volgende codevoorbeelden ziet u hoe matrices van primitieve gegevenstypen worden verwerkt. Het eerste voorbeeld is in X++ en het tweede voorbeeld is in C#. Beide monsters leveren dezelfde resultaten op.

X++ Sample

static void JobRs005a_ArraySimple(Args _args)
{
    #define.macroArrayLength(3)
    // Static length.
    str sSports[#macroArrayLength];
    // Dynamic length, changeable during run time.
    int years[];
    int xx;
    Global::warning("-------- SPORTS --------");
    sSports[#macroArrayLength] = "Baseball";
    for (xx=1; xx <= #macroArrayLength; xx++)
    {
        info(int2str(xx) + " , [" + sSports[xx] + "]");
    }
    warning("-------- YEARS --------");
    years[ 4] = 2008;
    years[10] = 1930;
    for (xx=1; xx <= 10; xx++)
    {
        info(int2str(xx) + " , " + int2str(years[xx]));
    }
}
Output

De uitvoer naar de Infolog is als volgt:

Message (14:16:08)
-------- SPORTS --------
1 , []
2 , []
3 , [Baseball]
-------- YEARS --------
1 , 0
2 , 0
3 , 0
4 , 2008
5 , 0
6 , 0
7 , 0
8 , 0
9 , 0
10 , 1930

C# Sample

using System;
public class Pgm_CSharp
{
    static public void Main( string[] args )
    {
        new Pgm_CSharp().ArraySimple();
    }
    private void ArraySimple()
    {
        const int const_iMacroArrayLength = 3;
        // In C# the length is set at construction during run.
        string[] sSports;
        int[] years;
        int xx;
        Console.WriteLine("-------- SPORTS --------");
        sSports = new string[const_iMacroArrayLength];
        sSports[const_iMacroArrayLength - 1] = "Baseball";
        for (xx=0; xx < const_iMacroArrayLength; xx++)
        {
            Console.WriteLine(xx.ToString() + " , [" + sSports[xx] + "]");
        }
        Console.WriteLine("-------- YEARS --------");
        // In C# you must construct the array before assigning to it.
        years = new int[10];
        years[ 4] = 2008;
        years[10 - 1] = 1930;
        for (xx=0; xx < 10; xx++)
        {
            Console.WriteLine(xx.ToString() + " , [" + years[xx].ToString() + "]");
        }
    }
} // EOClass
Output

De uitvoer van het C#-programma naar de opdrachtregelconsole is als volgt:

-------- SPORTS --------
0 , []
1 , []
2 , [Baseball]
-------- YEARS --------
0 , [0]
1 , [0]
2 , [0]
3 , [0]
4 , [2008]
5 , [0]
6 , [0]
7 , [0]
8 , [0]
9 , [1930]

Extra array-achtige X++-functies

De container is een speciaal gegevenstype dat beschikbaar is in X++. Het kan worden beschouwd als vergelijkbaar met een array of vergelijkbaar met een List verzameling.

Comparison: Collections

In een Finance and Operations-toepassing kunt u de X++ List -verzamelingsklasse gebruiken. Het .NET Framework dat in C# wordt gebruikt, heeft een vergelijkbare klasse met de naam System.Collections.Generic.List.

Het gebruik van de lijstklassen vergelijken

In de volgende tabel worden methoden voor de klasse X++ List vergeleken met de methoden voor System.Collections.Generic.List gebruik in .NET Framework en C#.

Feature X++ C# Comments
Verklaring van inzameling List myList; List<string> myList; De X++-declaratie bevat niet het type elementen dat moet worden opgeslagen.
Verklaring van iterator ListIterator iter
ListEnumerator enumer;
IEnumerator<string> iter; In X++ heeft het ListIterator object methoden die kunnen insert en delete items uit de List. De X++ ListEnumerator kan de inhoud van de List. In X++ wordt het ListEnumerator object altijd op dezelfde laag gemaakt als de List. Dit is niet altijd het geval voor ListIterator.
Het verkrijgen van een iterator new ListIterator (myList)
myList.getEnumerator()
myList.GetEnumerator() In zowel X++ als C# heeft het object List een getter methode voor een bijbehorende teller.
Constructor new List(Types::String) new List<string>() Informatie over het type objecten dat in de List klassen moet worden opgeslagen, wordt aan de constructor gegeven in zowel X++ als C#.
Updating data Teller – de teller wordt ongeldig als er items in de List worden toegevoegd of verwijderd.
Iterator – de iterator heeft methoden die items invoegen en verwijderen uit de List. De iterator blijft geldig.
Teller – de teller wordt ongeldig als er items in de List worden toegevoegd of verwijderd. Tellers worden ongeldig nadat items zijn toegevoegd aan of verwijderd uit de List, in zowel X++ als C#.
Updating data In X++ heeft de klasse methoden voor het List toevoegen van items aan het begin of einde van de lijst. In C# heeft de klasse methoden voor het List toevoegen van leden op elke positie in de lijst. Het heeft ook methoden om items uit elke positie te verwijderen. In X++ kunnen items alleen door List een iterator worden verwijderd.

Voorbeeld 1: Declaratie van een lijst

De volgende codevoorbeelden zijn in X++ en C# die verzamelingen declareren List .

// X++
List listStrings ,list2 ,listMerged;
ListIterator literator;
// C#
using System;
using System.Collections.Generic;
List<string> listStrings ,list2 ,listMerged; IEnumerator<string> literator;

Voorbeeld 2: Opbouw van een lijst

In beide talen moet het type artikelen dat de collectie opslaat worden gespecificeerd op het moment van constructie. Voor klassetypen kan X++ niet specifieker worden dan of het type een klasse is (Types::Class). De volgende codevoorbeelden zijn in X++ en C#.

// X++
listStrings = new List( Types::String );
// C#
listStrings = new List<string>;

Voorbeeld 3: Items toevoegen aan een lijst

In zowel X++ als C# biedt de verzameling een methode om een item aan het einde van de verzameling toe te voegen en om een item aan het begin in te voegen. In C# biedt de verzameling een methode voor het invoegen op elk punt in de verzameling op basis van een indexwaarde. In X++ kan een verzamelingiterator een artikel op de huidige positie invoegen. De volgende codevoorbeelden zijn in X++ en C#.

// X++
listStrings.addEnd ("StringBB."); 
listStrings.addStart ("StringAA.");
// Iterator performs a midpoint insert at current position. 
listIterator.insert ("dog");
// C#
listStrings.Add ("StringBB."); 
listStrings.Insert (0 ,"StringAA.");
// Index 7 determines the insertion point.
listStrings.Insert (7 ,"dog");

Voorbeeld 4: Een lijst doorlopen

Zowel X++ als C# hebben iteratorklassen die u kunt gebruiken om door de items in een verzameling te gaan, zoals wordt weergegeven in de volgende voorbeelden.

// X++
literator = new ListIterator (listStrings); 
// Now the iterator points at the first item.

// The more method answers whether 
// the iterator currently points 
// at an item. 
while (literator.more()) 
{ 
    info(any2str (literator.value())); 
    literator.next(); 
}
// C#
literator = listStrings .GetEnumerator(); 
// Now enumerator points before the first item, not at the first item.

// The MoveNext method both advances the item pointer, and 
// answers whether the pointer is pointing at an item. 
while (literator.MoveNext()) 
{ 
    Console.WriteLine (literator.Current); 
}

Voorbeeld 4b: foreach in C#

In C# wordt het foreach-trefwoord vaak gebruikt om de taak van het itereren van een lijst te vereenvoudigen. Het volgende codevoorbeeld gedraagt zich hetzelfde als het vorige C#-voorbeeld.

foreach (string currentString in listStrings)
{ 
    Console.WriteLine(currentString);
}

Voorbeeld 5: Het tweede item verwijderen

In de volgende codevoorbeelden wordt het tweede item uit de verzameling verwijderd. In X++ is hiervoor een iterator nodig. In C# biedt de collectie zelf de methode voor het verwijderen van een item.

// X++
literator.begin(); 
literator.next(); 
literator.delete();
// C#
listStrings.RemoveAt(1);

Voorbeeld 6: Twee collecties combineren

In de volgende codevoorbeelden wordt de inhoud van twee verzamelingen gecombineerd tot één.

// X++
listStrings = List::merge(listStrings ,listStr3);
// Or use the .appendList method:
listStrings.appendList (listStr3);
// C#
listStrings.InsertRange(listStrings.Count ,listStr3);

Vergelijking: Verzamelingen van sleutels met waarden

In een Finance and Operations-applicatie kunt u de Map incassoklasse gebruiken. De Map verzameling bevat paren van waarden, de sleutelwaarde plus een gegevenswaarde. Dit lijkt op de .NET Framework-klasse met de naam System.Collections.Generic.Dictionary.

Similarities

De volgende lijst beschrijft overeenkomsten tussen X++ en C# met betrekking tot hun collecties die sleutel-waardeparen opslaan:

  1. Beide voorkomen dubbele toetsen.
  2. Beide gebruiken een teller (of iterator) om door de items te lopen.
  3. Beide sleutel-waarde verzamelingsobjecten zijn geconstrueerd met aanduidingen van de typen die worden opgeslagen als sleutel en waarde.
  4. Beide kunnen klasse-objecten opslaan en zijn niet beperkt tot het opslaan van primitieven zoals int.

Differences

In de volgende tabel worden de verschillen beschreven tussen X++ en C# met betrekking tot hun verzamelingsklassen waarin sleutel-waardeparen worden opgeslagen:

Feature X++ C# Comments
Duplicate keys In X++ voorkomt de Map klasse dubbele sleutels door uw aanroep naar zijn insert methode impliciet te behandelen als een bewerking om alleen de waarde bij te werken die aan de sleutel is gekoppeld. In C# genereert de Dictionary klasse een uitzondering wanneer je een dubbele sleutel probeert toe te voegen. Dubbele sleutels worden in beide talen voorkomen, zij het met verschillende technieken.
Delete items In X++ wordt de delete methode op een iteratorobject gebruikt om een ongewenst sleutel-waardepaar uit een Map. In C# heeft de Dictionary class een remove methode. In beide talen wordt een teller ongeldig als het aantal collectiestukken tijdens de levensduur van de teller wordt gewijzigd.

Voorbeeld 1: Aangifte van een Key-Value collectie

In beide talen moet het type items worden opgegeven waarin de sleutelwaardeverzameling is opgeslagen. In X++ wordt het type gespecificeerd op het moment van constructie. In C# wordt het type zowel op het moment van aangifte als op het moment van constructie gespecificeerd. De volgende codevoorbeelden zijn in X++ en C#.

// X++
Map mapKeyValue;
MapEnumerator enumer;
MapIterator mapIter;
// C#
Dictionary<int,string> dictKeyValue;
IEnumerator<SysCollGen.KeyValuePair<int,string>> enumer;
KeyValuePair<int,string> kvpCurrentKeyValuePair;

Voorbeeld 2: Opbouw van de collectie

In beide talen het type items dat de sleutelwaarde-collectie opslaat tijdens de bouw heeft opgegeven. Voor klassetypen kan X++ niet specifieker worden dan of het type een klasse is (Types::Class). De volgende codevoorbeelden zijn in X++ en C#.

// X++
mapKeyValue = new Map(Types::Integer, Types::String);
// C#
dictKeyValue = new Dictionary<int,string>();

Voorbeeld 3: Een item toevoegen aan de collectie

Er is bijna geen verschil in de manier waarop een item wordt toegevoegd aan een sleutelwaardeverzameling in X++ en C#, zoals wordt weergegeven in de volgende codevoorbeelden.

// X++
mapKeyValue.insert(xx ,int2str(xx) + “_Value”);
// C#
dictKeyValue.Add(xx ,xx.ToString() + “_Value”);

Voorbeeld 4: Een Key-Value verzameling herhalen

Tellers worden gebruikt om door de sleutel-waardeverzamelingen in zowel X++ als C# te doorlopen, zoals wordt weergegeven in de volgende codevoorbeelden.

// X++ 
enumer = mapKeyValue.getEnumerator();
while (enumer.moveNext())
{
    iCurrentKey = enumer.currentKey();
    sCurrentValue = enumer.currentValue();
    // Display key and value here.
}
// C#
enumer = dictKeyValue.GetEnumerator();
while (enumer.MoveNext())
{
    kvpCurrentKeyValuePair = enumer.Current;
    // Display .Key and .Value properties=
    // of kvpCurrentKeyValuePair here.
}

Voorbeeld 5: De waarde bijwerken die aan een sleutel is gekoppeld

De syntaxis verschilt sterk tussen de twee talen voor een update van de waarde die aan een bepaalde sleutel is gekoppeld. De voorbeelden van de ollowing-code zijn voor de sleutel 102.

// X++
mapKeyValue.insert(
    102 ,
    ”.insert(), Re-inserted” + ” key 102 with a different value.”);
// C#
dictKeyValue[102] = 
    “The semi-hidden .item property in C#, Updated the value for key 102.”;

Voorbeeld 6: Eén item verwijderen

De syntaxis verschilt sterk tussen de twee talen om één sleutel-waardepaar uit een verzameling te verwijderen, terwijl de verzamelingsleden worden herhaald. Codevoorbeelden voor de sleutel 102 worden hieronder weergegeven.

// X++
mapIter = new MapIterator(mapKeyValue);
//mapIter.begin();
while (mapIter.more())
{
    iCurrentKey = mapIter.key();
    if (104 == iCurrentKey)
    {
        // mapKeyValue.remove would invalidate the iterator.
        mapIter.delete();
        break;
    }
    mapIter.next();
}
// C#
dictKeyValue.Remove(104);

Comparison: Exceptions

Er zijn enkele overeenkomsten, maar veel verschillen wanneer we uitzonderingsgerelateerd gedrag tussen X++ en C# vergelijken. De zoekwoorden proberen, vangen en gooien gedragen zich hetzelfde in X++ en C#. Maar de soorten uitzonderingen die worden gegooid en gevangen, zijn verschillend voor de twee talen.

Similarities

Overeenkomsten tussen X++ en C# met betrekking tot hun uitzonderingsfuncties zijn onder meer de volgende voorbeelden:

  • Beide talen hebben hetzelfde try-trefwoord .
  • Beide hebben hetzelfde trefwoord .
  • Beide maken een vangstverklaring mogelijk die geen specifieke uitzondering specificeert. Zo'n vangstaangifte vangt alle uitzonderingen op die hem bereiken.
  • Beide hebben hetzelfde trefwoord .

Differences

Uitzonderingsgerelateerde verschillen tussen X++ en C# worden beschreven in de volgende tabel.

Feature X++ C# Comments
retry Springt naar de eerste instructie in het bijbehorende try-blok . Zie Uitzonderingsafhandeling met trefwoorden proberen en vangen voor meer informatie. De functionaliteit van het trefwoord voor opnieuw proberen kan worden nagebootst in C#-code, maar er is geen bijbehorend trefwoord. Alleen X++ heeft een trefwoord voor opnieuw proberen . C# heeft geen tegenhanger. Zie X++, C#-vergelijking: automatisch opnieuw proberen na een uitzondering voor meer informatie.
finally Het finally zoekwoord wordt ondersteund om de try trefwoorden en catch te volgen. Het uiteindelijke trefwoord markeert een codeblok dat volgt op de try - en catch-blokken . De uiteindelijke zal worden uitgevoerd, ongeacht of er een uitzondering wordt gemaakt of gevangen. De semantiek is identiek aan de semantiek in C#.
Specific exceptions In X++ is een uitzondering een element van de Exception enum, zoals Error, Deadlock of CodeAccessSecurity. Geen enkele uitzondering kan een andere bevatten. In C# is een uitzondering een instantie van de System.Exception basisklasse, of een klasse die ervan erft. Een uitzondering kan worden opgenomen in de InnerException eigenschap van de gegenereerde uitzondering. In X++ is elke gegenereerde uitzondering een waarde van de Exception enum. Zie Opsomming van uitzonderingen voor meer informatie.
Exception message In X++ is het bericht dat wordt gemaakt wanneer een uitzondering wordt gegenereerd alleen beschikbaar in het infologboek en is het bericht niet rechtstreeks gekoppeld aan de uitzondering. In C# is het bericht het Message lid van het System.Exception object. In X++ is de Global::error methode het mechanisme dat uitzonderingsberichten weergeeft in de Infolog. Zie Uitzonderingsafhandeling met trefwoorden proberen en vangen voor meer informatie.
Exception conditions In X++ treedt een fout op wanneer u een instantiemethode aanroept op een objectvariabele waaraan nog niets is toegewezen. Er wordt echter geen uitzondering gemaakt samen met deze fout. Daarom kan geen catch enkel blok controle krijgen, zelfs niet als de niet-toegewezen variabele in een try blok wordt misbruikt. In het volgende codevoorbeeld zorgt de fout die door de code box4.toString(); wordt veroorzaakt er niet voor dat het besturingselement wordt overgedragen naar een catch blok: DialogBox box4;try { box4.toString();info("toString did not error, but expected an error."); } catch (Exception::Error) // No Exception-waarde vangt dit op. info("Invalid use of box4 gave control to catch, unexpected."); { } In C# wordt a System.NullReferenceException verhoogd wanneer een niet-geïnitialiseerde variabele wordt behandeld als een objectverwijzing. Er kunnen verschillende andere verschillen in de voorwaarden zijn die uitzonderingen oproepen.
SQL transactions Wanneer in X++ een SQL-uitzondering optreedt in een ttsBegin - ttsCommit-transactie , kan geen enkele catch statement in het transactieblok de uitzondering verwerken. In C# kan een catch block in een SQL-transactie de uitzondering opvangen.

Examples

De volgende X++-functies worden gedemonstreerd:

  • try keyword.
  • catch keyword.
  • Het gedrag na een uitzondering Exception::Error treedt op.

X++ Example

// X++
static void JobRs008a_Exceptions(Args _args)
{
    str sStrings[4];
    int iIndex = 77;
    try
    {
        info("On purpose, this uses an invalid index for this array: " + sStrings[iIndex]);
        warning("This message doesn't appear in the Infolog," + " it's unreached code.");
    }
    // Next is a catch for some of the values of
    // the X++ Exception enumeration.
    catch (Exception::CodeAccessSecurity)
    {
        info("In catch block for -- Exception::CodeAccessSecurity");
    }
    catch (Exception::Error)
    {
        info("In catch block for -- Exception::Error");
    }
    catch (Exception::Warning)
    {
        info("In catch block for -- Exception::Warning");
    }
    catch
    {
        info("This last 'catch' is of an unspecified exception.");
    }
    //finally
    //{
    //    //Global::Warning("'finally' is not an X++ keyword, although it's in C#.");
    //}
    info("End of program.");
}
Output

Hier is de uitvoer van het Infolog-venster:

Message (18:07:24)
Error executing code: Array index 77 is out of bounds.
Stack trace
(C)\Jobs\JobRs008a_Exceptions - line 8
In catch block for -- Exception::Error
End of program.

C# Sample

Het volgende C#-programma is een herschrijving van het vorige X++-programma.

// C#
using System;
public class Pgm_CSharp
{
    static void Main( string[] args )
    {
        new Pgm_CSharp().Rs008a_CSharp_Exceptions();
    }
    void Rs008a_CSharp_Exceptions()
    {
        //str sStrings[4];
        string[] sStrings = new string[4];
        try
        {
            Console.WriteLine("On purpose, this uses an invalid index for this array: " + sStrings[77]);
            Console.Error.WriteLine("This message doesn't appear in the Infolog, it's unreached code.");
        }
        catch (NullReferenceException exc)
        {
            Console.WriteLine("(e1) In catch block for -- " + exc.GetType().ToString() );
        }
        catch (IndexOutOfRangeException exc)
        {
            Console.WriteLine("(e2) In catch block for -- " + exc.GetType().ToString() );
        }
        // In C#, System.Exception is the base of all
        // .NET Framework exception classes.
        // No as yet uncaught exception can get beyond
        // this next catch.
        catch (Exception exc)
        {
            Console.WriteLine("This last 'catch' is of the abstract base type Exception: "
                + exc.GetType().ToString());
        }
        // The preceding catch of System.Exception makes this catch of
        // an unspecified exception redundant and unnecessary.
        //catch
        //{
        //    Console.WriteLine("This last 'catch' is"
        //        + " of an unspecified exception.");
        //}
        finally
        {
            Console.WriteLine("'finally' is not an X++ keyword, although it's in C#.");
        }
        Console.WriteLine("End of program.");
    }
} // EOClass
Output

Hier is de uitvoer naar de C#-console:

(e2) In catch block for -- System.IndexOutOfRangeException
'finally' is not an X++ keyword, although it's in C#.
End of program.

Vergelijking: Automatisch opnieuw proberen na een uitzondering

Soms kunt u code schrijven in een catch-blok waarmee de oorzaak van een uitzondering die tijdens de uitvoering optreedt, wordt opgelost. X++ biedt een trefwoord voor opnieuw proberen dat alleen binnen een catch-blok kan worden gebruikt. Met het trefwoord opnieuw proberen kan een programma terugspringen naar het begin van het try-blok nadat het probleem is gecorrigeerd door code in het catch-blok . C# heeft geen trefwoord voor opnieuw proberen . C#-code kan echter worden geschreven om gelijkwaardig gedrag te bieden.

Codevoorbeelden voor nieuwe pogingen

Het volgende X++-voorbeeldprogramma zorgt ervoor dat er een Exception::Error wordt gegenereerd. Dit gebeurt wanneer het voor het eerst probeert een element uit de sStrings matrix te lezen met behulp van een ongeldige indexwaarde. Wanneer de uitzondering wordt opgemerkt, worden corrigerende maatregelen genomen tijdens de looptijd in het vangblok . De retry-instructie springt vervolgens terug naar de eerste instructie in het tryblok . Deze tweede iteratie werkt zonder enige uitzondering tegen te komen.

static void JobRs008b_ExceptionsAndRetry(Args _args)
{
    str sStrings[4];
    str sTemp;
    int iIndex = 0;

    sStrings[1] = "First array element.";
    try
    {
        print("At top of try block: " + int2str(iIndex));
        sTemp = sStrings[iIndex];
        print( "The array element is: " + sTemp );
    }
    catch (Exception::Error)
    {
        print("In catch of -- Exception::Error (will retry)." + " Entering catch.");
        ++iIndex;
        print("In catch of -- Exception::Error (will retry)." + " Leaving catch.");
        // Here is the retry statement.
        retry;
    }
    print("End of X++ retry program.");
    pause;
}

Output

Hier is de uitvoer naar het afdrukvenster:

At top of try block: 0
In catch of -- Exception::Error (will retry). Entering catch.
In catch of -- Exception::Error (will retry). Leaving catch.
At top of try block: 1
The array element is: First array element.
End of X++ retry program.

C# Sample

Het volgende C#-voorbeeld is geen regel-voor-regel vertaling van het vorige X++-voorbeeld. In plaats daarvan heeft het C#-programma een andere structuur, zodat het het gedrag van het trefwoord opnieuw proberen nabootst waarop het X++-programma vertrouwt. De try and catch-blokken zijn in een aangeroepen methode. De variabelen die in het try-blok worden gebruikt, worden opgeslagen in de aanroepmethode. De aanroepmethode geeft de variabelen door als parameters die zijn versierd met het trefwoord ref , zodat hun waarden kunnen worden gecorrigeerd in het catch-blok van de aangeroepen methode. De aangeroepen methode legt alle uitzonderingen vast en retourneert een booleaanse terugkoppeling naar de aanroeper of een tweede aanroep nodig is.

// C#
using System;
public class Pgm_CSharp
{
    static void Main(string[] args)
    {
        new Pgm_CSharp() .Rs008b_CSharp_ExceptionsAndRetry();
    }
    void Rs008b_CSharp_ExceptionsAndRetry() // Caller
    {
        int iIndex = -1
            , iNumRetriesAllowed = 3;
        bool bReturnCode = true; // Means call the callee method.
        for (int xx=0; xx <= iNumRetriesAllowed; xx++)
        {
            if (bReturnCode)
            {
                bReturnCode = this.Rs008b_CSharp_ExceptionsAndRetry_Callee(ref iIndex);
            }
            else
            {
                break;
            }
        }
        Console.WriteLine("End of C# caller method.");
    }
    
    private bool Rs008b_CSharp_ExceptionsAndRetry_Callee(ref int iIndex)
    {
        bool bReturnCode = true; // Means call this method again.
        string[] sStrings = new string[4];
        string sTemp;
        sStrings[0] = "First array element.";
        try
        {
            Console.WriteLine("At top of try block: " + iIndex.ToString());
            sTemp = sStrings[iIndex];
            Console.WriteLine( "The array element is: " + sTemp );
            bReturnCode = false; // Means do not call this method again.
        }
        catch (Exception)
        {
            Console.WriteLine("In catch of -- Exception. Entering catch.");
            ++iIndex; // The 'ref' parameter in C#.
            Console.WriteLine("In catch of -- Exception. Leaving catch.");
            //retry;
            // In C# we let the caller method do the work
            // that the retry keyword does in X++.
        }
        Console.WriteLine("End of C# callee method.");
        return bReturnCode;
    }
}

Output

Hier is de uitvoer naar de console:

At top of try block: -1
In catch of -- Exception. Entering catch.
In catch of -- Exception. Leaving catch.
End of C# callee method.
At top of try block: 0
The array element is: First array element.
End of C# callee method.
End of C# caller method.

Comparison: Operators

In deze sectie worden de operatoren tussen X++ en C# vergeleken.

Assignment Operators

In de volgende tabel worden de verschillen weergegeven tussen de toewijzingsoperatoren in X++ en C#.

X++ en C# Differences
= In X++ veroorzaakt deze operator een impliciete conversie wanneer er een verlies aan precisie optreedt, bijvoorbeeld voor een toewijzing van een int64 naar een int. Maar in C# veroorzaakt de toewijzing een compilatiefout.
+= en -= Het enige verschil is dat in C# deze operatoren ook worden gebruikt bij het manipuleren van gedelegeerden.
++ en -- Dit zijn de increment en decrement operatoren in beide talen. De volgende regel is in beide talen identiek:
++myInteger;
Maar in X++ zijn deze twee operatoren voor statements, niet voor expressies. Daarom genereren de volgende regels compilatiefouten in X++:
myStr = int2str(++myInteger);
myIntA = myIntBB++;

Arithmetic Operators

De volgende tabel geeft een overzicht van de rekenkundige operatoren.

X++ en C# Differences
* Als vermenigvuldiger zijn er geen verschillen.

Notitie: Het sterretje wordt ook gebruikt in de SQL-statements die deel uitmaken van de X++-taal. In deze SQL-instructies kan het sterretje ook een van de volgende zijn:

  • Een jokerteken dat aangeeft dat alle kolommen moeten worden geretourneerd.
  • Een jokerteken voor tekens in een tekenreeks die wordt gebruikt voor een like-clausule .
/ De divisie-operator is hetzelfde in X++ en C#.
MOD Voor modulo-bewerkingen is het enige verschil dat het %-symbool wordt gebruikt in C#.
+ De opteloperator is hetzelfde in X++ en C#. Het plusteken wordt ook gebruikt voor aaneenschakeling van tekenreeksen. Deze operator voegt getallen toe en voegt tekenreeksen in beide talen samen.
- De aftrekoperator is hetzelfde in X++ en C#.

Bitwise Operators

In de volgende tabel worden de bitsgewijze operatoren tussen X++ en C# vergeleken.

X++ en C# Differences
<< De linker ploegoperator is hetzelfde in X++ en C#.
>> De rechter shiftoperator is hetzelfde in X++ en C#.
~ De bitsgewijze NOT-operator is hetzelfde in X++ en C#.
& De binaire AND-operator is hetzelfde in X++ en C#.
^ De binaire XOR-operator is hetzelfde in X++ en C#.

Relational Operators

De volgende relationele operatoren zijn hetzelfde in X++ en C#:

  • ==
  • <=
  • <=
  • >
  • <
  • !=
  • &&
  • ||
  • !
  • ? :

Comparison: Events

Er zijn enkele verschillen in de manier waarop X++ en C# het gebeurtenisontwerppatroon implementeren. Zie Terminologie en trefwoorden voor evenementen voor meer informatie.

Vergelijking van gebeurtenissen tussen X++ en C#

Er zijn verschillen in de manier waarop afgevaardigden worden gebruikt voor evenementen in X++ versus C#.

Concept X++ C# Comments
delegate In X++ kan een gemachtigde alleen als lid van een klas worden gedeclareerd. Een gemachtigde kan geen lid zijn van een tabel. Alle afgevaardigden zijn bijvoorbeeld leden van hun klas, geen statische leden. Er kan geen toegangsmodifier worden gebruikt voor een gemachtigdendeclaratie, omdat alle gemachtigden beveiligde leden zijn. Daarom kan de gebeurtenis alleen worden aangemaakt door middel van een code binnen dezelfde klasse als waar de gemachtigde lid van is. De enige uitzondering op het privékarakter van een gedelegeerde is echter dat code buiten hun klasse op de delegates kan werken met behulp van de operatoren += en -=. In C# is elke gedelegeerde een type, net zoals elke klasse een type is. Een afgevaardigde wordt onafhankelijk van een klasse verklaard. Zonder het gebeurtenistrefwoord kunt u een gemachtigde als parametertype op een methode hebben, net zoals u een klasse als parametertype kunt hebben. U kunt een exemplaar van een gemachtigde maken die moet worden doorgegeven voor de parameterwaarde. In X++ is elke klasse een type, maar geen enkele delegate is een type. U kunt geen exemplaar van een gemachtigde maken. Geen enkele afgevaardigde kan een parameter zijn voor een methode. U kunt echter een klasse maken met een gedelegeerd lid en u kunt exemplaren van de klasse doorgeven als parameterwaarden. Zie X++-trefwoorden voor meer informatie.
event In code X++ is een gebeurtenis een van de volgende:
  • Een expliciete oproep aan een gemachtigde.
  • Het begin of einde van een methode.
Er is geen trefwoord voor gebeurtenissen in X++.
In C# wordt het trefwoord gebeurtenis gebruikt om een gedelegeerd type te declareren als lid van een klas. Het effect van het trefwoord gebeurtenis is dat de gemachtigde wordt beveiligd, maar nog steeds toegankelijk is voor de operators += en -=. U kunt gebeurtenishandlermethoden abonneren op een gebeurtenis met behulp van de operator +=. Een gedelegeerde kan nuttig zijn zonder het trefwoord gebeurtenis , als een techniek voor het doorgeven van een functieaanwijzer als parameter aan een methode. De automatische gebeurtenissen die plaatsvinden vóór het begin van een methode en na het einde van een methode, kunnen alleen worden geabonneerd met behulp van de AOT.
+= en -= operatoren In X++ gebruikt u de operator += om methoden te abonneren op een gemachtigde. De operator -= schrijft een methode uit bij een gemachtigde. In C# gebruikt u de operator += om u te abonneren op een gebeurtenis of op een gemachtigde die niet wordt gebruikt met het gebeurtenistrefwoord. De gemachtigde bevat een verwijzing naar alle objecten waarvoor methoden zijn geabonneerd op de gemachtigde. Deze objecten komen niet in aanmerking voor afvalinzameling, terwijl de gemachtigde deze verwijzingen bezit.
eventHandler In X++ is het trefwoord eventHandler vereist wanneer u de operator += of -= gebruikt om een methode van een gemachtigde te abonneren of af te melden. System.EventHandler is een gemachtigde type in het .NET Framework. Deze term wordt in X++ anders gebruikt dan in C# of het .NET Framework. Zie X++-trefwoorden voor meer informatie.

X++ Example

De belangrijke dingen om op te merken zijn de volgende in het X++-voorbeeld:

  • Het XppClass heeft een afgevaardigd lid dat de naam myDelegate.

    Note

    De AOT bevat een knooppunt voor de gemachtigde. Het knooppunt bevindt zich op AOT > Classes > XppClass > myDelegate. Onder het knooppunt myDelegate kunnen verschillende knooppunten voor gebeurtenishandlers worden geplaatst. Event handlers die worden vertegenwoordigd door knooppunten in de AOT kunnen tijdens de runtime niet worden verwijderd door de -= operator.

  • De {} accolades aan het einde van de gemachtigde declaratie zijn vereist, maar ze mogen geen code bevatten.

  • De XppClass heeft twee methoden waarvan de parameterhandtekeningen compatibel zijn met de gedelegeerde. Eén methode is statisch.

  • De twee compatibele methoden worden toegevoegd aan de gemachtigde met de operator += en het trefwoord eventHandler . Deze instructies roepen de gebeurtenishandler-methoden niet aan, de instructies voegen alleen de methoden toe aan de gemachtigde.

  • De gebeurtenis wordt verhoogd door één oproep aan de gemachtigde.

  • De parameterwaarde die aan de gemachtigde is doorgegeven, wordt ontvangen door elke gebeurtenishandlermethode.

  • De korte X++-taak bovenaan het voorbeeld start de test.

// X++
// Simple job to start the delegate event test.
static void DelegateEventTestJob()
{
    XppClass::runTheTest("The information from the X++ job.");
}
// The X++ class that contains the delegate and the event handlers.
class XppClass
{
    delegate void myDelegate(str _information)
    {
    }
    public void myEventSubscriberMethod2(str _information)
    {
        info("X++, hello from instance event handler 2: " + _information);
    }
    static public void myEventSubscriberMethod3(str _information)
    {
        info("X++, hello from static event handler 3: " + _information);
    }
    static public void runTheTest(str _stringFromJob)
    {
        XppClass myXppClass = new XppClass();
        // Subscribe two event handler methods to the delegate.
        myXppClass.myDelegate += eventHandler(myXppClass.myEventSubscriberMethod2);
        myXppClass.myDelegate += eventHandler(XppClass::myEventSubscriberMethod3);
        // Raise the event by calling the delegate one time,
        // which calls all the subscribed event handler methods.
        myXppClass.myDelegate(_stringFromJob);
    }
}

De uitvoer van de vorige X++-taak is als volgt:

X++, hello from static event handler 
3: The information from the X++ job. X++, hello from instance event handler 
2: The information from the X++ job.

C# Sample

Deze sectie bevat een C#-codevoorbeeld voor het gebeurtenisontwerppatroon van het vorige X++-voorbeeld.

// C#
using System;
// Define the delegate type named MyDelegate.
public delegate void MyDelegate(string _information);
public class CsClass
{
    protected event MyDelegate MyEvent;
    static public void Main()
    {
        CsClass myCsClass = new CsClass();
        // Subscribe two event handler methods to the delegate.
        myCsClass.MyEvent += new MyDelegate(myCsClass.MyEventSubscriberMethod2);
        myCsClass.MyEvent += new MyDelegate(CsClass.MyEventSubscriberMethod3);
        // Raise the event by calling the event one time, which
        // then calls all the subscribed event handler methods.
        myCsClass.MyEvent("The information from the C# Main.");
    }
    public void MyEventSubscriberMethod2(string _information)
    {
        Console.WriteLine("C#, hello from instance event handler 2: " + _information);
    }
    static public void MyEventSubscriberMethod3(string _information)
    {
        Console.WriteLine("C#, hello from static event handler 3: " + _information);
    }
}

De uitvoer van het vorige C#-voorbeeld is als volgt:

CsClass.exe C#, hello from instance event handler 
2: The information from the C\# Main. C\#, hello from static event handler 
3: The information from the C\# Main.

Evenementen en de AOT

Er zijn andere evenementensystemen die alleen van toepassing zijn op items in de AOT. Zie Event Handler Nodes in de AOT voor meer informatie.

Vergelijking: Precompiler-richtlijnen

X++ en C# delen enkele trefwoorden voor hun precompiler directive syntaxis, maar de betekenissen zijn niet altijd hetzelfde.

Similarities

De X++ en C# compilers herkennen veel van dezelfde zoekwoorden. In de meeste gevallen betekenen de trefwoorden hetzelfde voor beide taalcompilers.

Differences

Een fundamenteel verschil tussen de precompiler-directives in X++ versus C# is het #define trefwoord dat beide taalprecompilers herkennen. In tegenstelling tot C# vereist de #define instructie in X++ een punt in de syntaxis. In X++ kunnen haakjes worden gebruikt om het gedefinieerde symbool een waarde te geven. Deze verschillen worden weergegeven in de volgende voorbeelden:

  • In X++: #define. Initieel Jaar(2003)
  • In C#: #define InitialYear

Een klein verschil is dat er in C# spaties en tabtekens kunnen staan tussen het #-teken en het instructieve trefwoord, zoals # define Testing.

Identical Keywords

De volgende tabel bevat precompiler-richtlijnen die vergelijkbaar zijn in X++ en C#.

Keyword X++ C# Comments
#define In X++ kan de naam van een precompiler-variabele worden gedefinieerd en kan aan die variabele een waarde worden gegeven. In C# kan de naam van een precompiler-variabele worden gedefinieerd, maar er kan geen waarde aan die variabele worden gegeven. Bovendien moet een #define in C# boven aan het bestand voorkomen en mag deze niet plaatsvinden na een code, zoals een gebruiksinstructie of een klassedeclaratie. De C#-compiler kan een opdrachtregelparameter invoeren om de naam van /define een precompiler-variabele te definiëren zonder de variabele in een C#-codebestand te definiëren. De X++ compiler heeft geen tegenhanger van /define.
#if In X++ kun #if bepalen of er een precompilervariabele bestaat en of de variabele een bepaalde waarde heeft. In C# kun #if alleen bepalen of er een precompilervariabele bestaat. Er kan niet op een waarde worden getest omdat er geen waarde aan kan worden toegewezen.
#endif In X++ markeert #endif het einde van een #if blok. Het eindigt ook een #ifnot blok. In C# markeert #endif het einde van een #if blok, ongeacht of het blok een #else bevat.

Verschillende zoekwoorden met hetzelfde verwerkingsresultaat

De volgende tabel bevat precompiler-directives die in X++ en C# een andere naam hebben, maar die dezelfde resultaten geven wanneer ze worden verwerkt.

X++ C# Comments
#ifnot #if #else Er is geen #else richtlijn in X++, maar de #ifnot biedt vergelijkbare functionaliteit. In X++ kun #ifnot bepalen of er een precompilervariabele bestaat en of de variabele geen specifieke gegeven waarde heeft. In C# kunt #if bepalen of er een precompiler-variabele bestaat wanneer de '!' symbool wordt voorafgegaan door de naam van de variabele.
//BP Deviation documented #pragma warning Deze X++ en C# items zijn niet equivalent, maar er is een gedeeltelijke overeenkomst. Beide onderdrukken compilerwaarschuwingsberichten.
#macrolib . HPP-bestand in C++ Er is een gedeeltelijke overeenkomst tussen de X++-richtlijn #macrolib versus een . HPP-bestand in C++. Beide kunnen meerdere #define verklaringen bevatten.

Precompiler-richtlijnen exclusief voor X++

De volgende tabel geeft een overzicht van X++ precompiler-directives die geen directe tegenhanger hebben in C#.

X++ Comments
#linenumber De #linenumber richtlijn is voor het verkrijgen van het regelnummer, zodat het kan worden uitgevoerd naar de Infolog.
De C#-richtlijn #line is anders omdat het doel ervan is om het regelnummer in te stellen.
#defdec #definc
#globaldefine In X++ is er een klein verschil tussen #globaldefine versus #define. Het verschil is dat #globaldefine nooit een huidige niet-nullwaarde overschrijft die door #define aan een precompilervariabele is toegewezen.
C# heeft niets vergelijkbaars met dit verschil, omdat in C# de naam van een precompiler-variabele geen waarde kan krijgen.
#localmacro #macro In X++ kunt u met #localmacro een waarde voor meerdere regels toewijzen aan een precompilervariabele. #macro is een synoniem, maar #localmacro is aan te raden.
In C# heeft de #define-instructie een deel van deze functionaliteit, maar kan deze geen waarde toewijzen aan een precompiler-variabele.
#globalmacro In X++ is #globalmacro bijna hetzelfde als de voorkeurs#localmacro.

Vergelijking: Objectgeoriënteerd programmeren

De objectgeoriënteerd programmeren (OOP) principes van X++ verschillen van C#.

Conceptual Comparisons

De volgende tabel vergelijkt de implementatie van OOP-principes tussen X++ en C#.

Feature X++ C# Comments
Casting De X++-taal heeft de trefwoorden is en as, die worden gebruikt om downcasts veilig en expliciet te maken. Tip: X++ vereist niet het gebruik van het trefwoord als wanneer u een basisklassevariabele downcast naar een afgeleide klassevariabele. We raden echter aan om in alle sombere uitspraken het als trefwoord te gebruiken. Een object kan zowel omhoog als omlaag worden geworpen op het overervingspad. Sombevelens vereisen het als trefwoord. Voor meer informatie over de X++ trefwoorden is en as, zie Expressie Operatoren: Is en As voor Overerving.
Local functions Een methode kan een declaratie en een codetekst bevatten voor nul of meer lokale functies. Alleen die methode kan aanroepen naar de lokale functie hebben. C# 3.0 ondersteunt lambda-expressies, die enige gelijkenis vertonen met anonieme functies en lokale functies. Lambda-uitdrukkingen worden vaak gebruikt met afgevaardigden.
Method overloading Overbelasting van de methode wordt niet ondersteund. Een methodenaam kan slechts één keer per klasse voorkomen. Overbelasting van de methode wordt ondersteund. Een methodenaam kan meerdere keren voorkomen in één klasse, met telkens verschillende parameterhandtekeningen. X++ ondersteunt optionele parameters voor methoden. Optionele parameters kunnen de overbelasting van de methode gedeeltelijk nabootsen. Zie de rij voor optionele parameters in deze tabel voor meer informatie.
Method overriding Methode overschrijven wordt ondersteund. Een afgeleide klasse kan een methode hebben met dezelfde naam als in de basisklasse, zolang de parameterhandtekening in beide gevallen hetzelfde is. De enige uitzondering is dat de overschrijvende methode een standaardwaarde aan een parameter kan toevoegen. Methode overschrijven wordt ondersteund. Het virtuele trefwoord moet worden toegepast op een methode voordat de methode kan worden overschreven in een afgeleide klasse. Het concept van het overschrijven van een methode omvat de naam van de methode, de parameterhandtekening en het retourtype. Het concept van methode overschrijven is niet van toepassing als de basismethode en de overheersende methode in een van deze aspecten verschillen.
Optional parameters Een parameterdeclaratie kan worden gevolgd door een standaardwaardetoewijzing. De methodeaanroeper heeft de mogelijkheid om een waarde voor die parameter door te geven of de parameter te negeren om de standaardwaarde te accepteren. Deze functie bootst overbelasting van de methode na, omdat twee aanroepen naar dezelfde methodenaam verschillende aantallen parameters kunnen doorgeven. Elke parameter met een standaardwaarde moet de laatste parameter volgen die geen standaardwaarde heeft. Optionele parameters worden ondersteund door het trefwoord params . Zelfs zonder het trefwoord params , vanuit het oogpunt van de aanroeper, kan overbelasting van de methode gedeeltelijk vergelijkbare functionaliteit bieden. Zie Parameters en bereik en Optionele parameters gebruiken voor meer informatie.
Single inheritance U kunt uw X++-klasse afleiden uit een andere X++-klasse door het trefwoord extend te gebruiken in het classDeclaration-knooppunt van uw klasse, in de AOT. Geen enkele klasse komt impliciet rechtstreeks voort uit een andere klasse. Als u wilt dat uw klasse rechtstreeks uit de Object klasse voortkomt, moet u het trefwoord extend gebruiken. U kunt slechts één klasse opgeven voor het trefwoord Extens .

Let op: Wanneer u een X++-basisklasse wijzigt waarvan andere klassen zijn afgeleid, moet u die basisklasse opnieuw compileren met behulp van de knop Vooruit compileren. Deze optie zorgt ervoor dat de afgeleide klassen ook opnieuw worden gecompileerd. Als u ervoor wilt zorgen dat de afgeleide klassen ook opnieuw worden gecompileerd, klikt u met de rechtermuisknop op het knooppunt van de basisklasse en klikt u vervolgens op Add-Ins > Vooruit compileren. Het alternatief om op Build > Compile te klikken (of op de F7-toets te drukken) is soms onvoldoende voor een wijziging van de basisklasse.

Een klasse kan nul tot veel interfaces implementeren.

Een X++-tabel erft impliciet van de Common tabel en van de xRecord klasse.
C# gebruikt het trefwoord extend om af te leiden van een andere klasse. Alle .NET Framework-klassen zijn impliciet afgeleid van de klasse, tenzij ze expliciet zijn afgeleid van een System.Object andere klasse.

Keyword Comparisons

De volgende tabel bevat de OOP-gerelateerde zoekwoorden in X++ en C#.

Keyword X++ C# Comments
abstract No difference.
class De modifiers public en private worden genegeerd in class declaraties. Er is geen concept van een naamruimtegroepering van klassen. Er zijn geen punten (.) in klassenamen. De modifiers public en private kunnen worden gebruikt om klassedeclaraties te wijzigen. C# heeft ook het sleutelwoord intern, dat betrekking heeft op de manier waarop klassen worden gegroepeerd in assembly-bestanden. Er is geen concept van een beschermde klasse, alleen beschermde leden van een klasse.
extends Een klassedeclaratie kan worden overgenomen van een andere klasse met behulp van het trefwoord extens . Een dubbele punt (:) wordt gebruikt waar de trefwoorden zich uitstrekken en implements worden gebruikt in X++.
final Een uiteindelijke methode kan niet worden overschreven in een afgeleide klasse. Een laatste les kan niet worden verlengd. Het trefwoord verzegeld op een klasse betekent hetzelfde als definitief betekent op een X++ klasse.
implements Een klassedeclaratie kan een interface implementeren met behulp van het trefwoord implements .
interface Een interface kan methoden specificeren die de klasse moet implementeren. Een interface kan methoden specificeren die de klasse moet implementeren.
new Het nieuwe trefwoord wordt gebruikt om een nieuw exemplaar van een klasse toe te wijzen. Dan wordt de constructeur automatisch aangeroepen. Elke klasse heeft precies één constructor en de constructor wordt genoemd new. U kunt zelf bepalen welke parameters de constructor moet invoeren. Het nieuwe trefwoord wordt gebruikt om een nieuw exemplaar van een klasse te maken. Dan wordt de constructeur automatisch aangeroepen. Constructormethoden zelf hebben geen naam new, ze hebben dezelfde naam als de klasse.

Notitie: Het nieuwe trefwoord kan ook worden gebruikt op een methode, om de manier te wijzigen waarop de methode dezelfde methode in de basisklasse overschrijft.

Zowel X++ als C# gaan uit van een standaardconstructor voor klassen waarvoor geen constructor expliciet in hun code is geschreven.
null No difference.
Privé en beschermd De private en protected trefwoorden kunnen worden gebruikt om de declaratie van een klasselid te wijzigen. De private en protected trefwoorden kunnen worden gebruikt om de declaratie van een klasselid te wijzigen.
public Een methode die niet is gewijzigd met openbaar, beveiligd of privé , heeft het standaardtoegangsniveau van openbaar. Een methode die niet is gewijzigd met openbaar, beveiligd of privé, heeft het standaardtoegangsniveau privé.
static Een methode kan statisch zijn, maar een veld kan dat niet. Zowel methoden als velden kunnen statisch zijn.
super Het superzoekwoord wordt gebruikt in een afgeleide klasse om toegang te krijgen tot dezelfde methode in de basisklasse. void method2()
{
// Call method2 method
// on the base class.
super();
}
Het basiszoekwoord wordt gebruikt in een afgeleide klasse om toegang te krijgen tot verschillende methoden in de basisklasse.
void method2()
{
// Call methods on
// the base class.
base.method2();
base.method3();
}
In C# is er een speciale syntaxis voor het gebruik van de basis om de basisconstructor aan te roepen.
this Voor een aanroep van de ene instantiemethode naar de andere op hetzelfde object is een kwalificatie voor de aangeroepen methode vereist. Het trefwoord dit is beschikbaar als qualifier voor het huidige object. Voor een aanroep van de ene instantiemethode naar de andere op hetzelfde object is een kwalificatie voor de aangeroepen methode niet vereist. Dit zoekwoord is echter beschikbaar als kwalificatie voor het huidige object. In de praktijk kan het trefwoord dit nuttig zijn door IntelliSense-informatie weer te geven.
finalize De Object les bevat de finalize methode. De finalize methode is niet definitief en kan worden overschreven. De finalize methode lijkt op de System.Object.Finalize methode in C#, maar in X++ heeft de finalize methode geen enkele speciale betekenis. Een object wordt automatisch uit het geheugen verwijderd wanneer de laatste verwijzing naar het object niet meer naar het object verwijst. Dit kan bijvoorbeeld gebeuren wanneer de laatste verwijzing buiten het bereik valt of er een ander object aan wordt toegewezen om naar te verwijzen. De methoden Finalize en Dispose zijn gebruikelijk bij sommige soorten lessen. De vuilnisman roept de Finalize en Dispose methoden wanneer het vernietigt en bezwaar. In C# kan de System.GC.Collect methode in het .NET Framework worden aangeroepen om de garbage collector te starten. Er is geen vergelijkbare functie in X++ omdat X++ een deterministische garbage collector gebruikt.
main Klassen die vanuit een menu worden aangeroepen, hebben hun main methode aangeroepen door het systeem. Klassen die worden aangeroepen vanaf een opdrachtregelconsole hebben hun Main methode aangeroepen door het systeem.

Comparison: Classes

Wanneer u C# gebruikt in het .NET Framework, worden klassen gegroepeerd in naamruimten. Elke naamruimte richt zich op een functioneel gebied, zoals bestandsbewerkingen of reflectie. Wanneer u de klassen echter in X++ gebruikt, zijn er geen zichtbare groeperingen zoals een naamruimte.

Vergelijking: Lessen over Reflectie

In X++ biedt de TreeNode klasse toegang tot de Application Object Tree (AOT). De TreeNode klasse is het centrum van reflectiefunctionaliteit in X++. De TreeNode klasse en de bijbehorende methoden kunnen worden vergeleken met de System.Reflection naamruimte in het .NET Framework die C# gebruikt.

In de volgende tabel worden verschillende klassen weergegeven die voor u beschikbaar zijn wanneer u C#-code schrijft. Dit zijn .NET Framework-klassen. Voor deze tabel staan alle C#-klassen in de System.Reflection naamruimte, tenzij anders aangegeven. Elke rij toont de corresponderende klasse, of het bijbehorende klasselid, dat voor u beschikbaar is wanneer u X++-code schrijft.

X++ C# Comments
TreeNode System .Assembly Assembly is de eerste klasse die kan worden gebruikt wanneer een C#-programma reflectie-informatie moet verzamelen. Statische methoden op de X++-klasse TreeNode zijn het uitgangspunt voor reflectie in X++.
TreeNode System .Type Instantiemethoden op TreeNode komen overeen met instantiemethoden op System.Type.
TreeNode .AOTgetSource MethodInfo De AOTgetSource methode retourneert meerdere stukjes informatie samen in één string. Dit omvat de X++-broncode in de methode. Heeft daarentegen MethodInfo een afzonderlijk lid voor elk stukje informatie.
TreeNode .AOTfirstChild TreeNode .AOTnextSibling TreeNode .AOTiterator AOTiterator MethodInfo (een array) In C# retourneert de GetMethods methode op System.Type een matrix van MethodInfo-objecten. U kunt de matrix doorlopen met de gebruikelijke techniek van het verhogen van een indexeerfunctie. Het X++-model daarentegen is bedoeld om door de boomstructuur van de AOT te navigeren. De TreeNode methoden van AOTfirstChild en AOTnextSibling volbrengen van de navigatie. Als een gelijkwaardig alternatief is de X++ AOTiterator -klasse ontworpen om door de boomstructuur van de AOT te navigeren. Een klasseknooppunt is de bovenliggende waarde van verschillende methodeknooppunten. De AOTiterator stappen door onderliggende knooppunten, die elk terugkeren als een andere TreeNode instantie. Aanvullende bronnen de TreeNode methoden die worden genoemd AOTparent en AOTprevious.
TreeNode .AOTgetProperty TreeNode .AOTgetProperties TreeNode .AOTname PropertyInfo In X++ geeft de AOTgetProperties methode een lange string terug die naam-waardeparen bevat voor alle eigenschappen van de TreeNode. De AOTname methode retourneert een tekenreeks die alleen de waarde voor de eigenschap naam bevat.
TreeNode .AOTsave TreeNode .AOTinsert System .Reflection .Emit (naamruimte van klassen) De AOTsave methode past wijzigingen van een TreeNode object in uw X++-code toe op de AOT en de wijzigingen worden behouden. Zie TreeNode.AOTsave-methode voor een groot codevoorbeeld.

Vergelijking: Lessen over File IO

Er zijn verschillende klassen die bestandsinvoer- en uitvoerbewerkingen (IO) uitvoeren. In het .NET Framework dat wordt gebruikt in C#, bevinden de tegenhangers van deze klassen zich in de System.IO naamruimte.

In de volgende tabel worden verschillende .NET Framework-klassen voor C# weergegeven die zich in de System.IO naamruimte bevinden. Elke rij in de tabel bevat de klasse of methode X++ die het beste overeenkomt met de klasse .NET Framework.

X++ C# Comments
BinaryIo FileStream BinaryReader BinaryWriter X++ klassen zoals BinaryIo die zich uitstrekken van de abstracte klasse Io dienen als een stroom, en ze dienen ook als een lezer en schrijver voor die stroom. In C# is de stream een aparte klasse van de klasse met meer specifieke lees- en schrijfmethoden.
TextBuffer MemoryStream Deze klassen bevatten een buffer in het geheugen en sommige methoden behandelen de buffer alsof het een bestand op de harde schijf is.
WINAPI::createDirectory WINAPI::folderBestaat WINAPI::removeDirectory Directory DirectoryInfo Path X++ kan statische methoden in de klasse gebruiken voor veel basisfuncties van het WINAPI besturingssysteem die betrekking hebben op mappen.
WINAPI::getDriveType DriveInfo DriveType Deze klassen en methoden worden gebruikt om rijgerelateerde informatie te verkrijgen.
WINAPI::copyFile WINAPI::createFile WINAPI::d eleteFile WINAPI::fileExists File FileAttributes FileInfo X++ kan statische methoden in de klasse gebruiken voor veel basisfuncties van het WINAPI besturingssysteem die betrekking hebben op bestanden.
CommaIo Comma7Io (Geen overeenkomstige klasse.) Deze X++-klassen kunnen bestanden genereren die Microsoft Excel kan importeren. In X++ is een EPPlus-bibliotheekreferentie beschikbaar voor extra interactie met Excel.
AsciiIo TextIo FileStream TextReader TextWriter Deze klassen gebruiken verschillende codepagina's.
Io Stream StreamReader StreamWriter FileStream Deze worden vaak gebruikt als basisklassen die andere klassen uitbreiden.
CodeAccessPermission FileIoPermission System.Security .CodeAccessPermission De naamruimte System.Security.Permissions bevat de volgende klassen:
  • CodeAccessSecurityAttribute
  • FileIOPermissionAttribute
  • FileIOPermission
  • FileIOPermissionAccess
De concepten en methoden van assert, demand, en revertAssert zijn van toepassing op beide talen. De deny and-methoden revertDeny die beschikbaar zijn in C# zijn echter niet beschikbaar in X++.

X++, ANSI SQL-vergelijking: SQL Select

In X++ verschilt de syntaxis van de SQL select-instructie van de specificatie van het American National Standards Institute (ANSI).

Enkele tafel selecteren

In de volgende tabel worden de verschillen weergegeven tussen de select-instructies van X++ SQL en ANSI SQL.

Feature X++ SQL ANSI SQL Comments
Tabelnaam op de van-clausule . De van-component bevat een recordbufferexemplaar dat wordt gedeclareerd vanuit een tabel, zoals vanuit de CustTable tabel. De from-clausule bevat een tabelnaam, niet de naam van een buffer. De recordbuffer bevat alle methoden die de xRecordklasse heeft in X++.
Syntaxisvolgorde van de volgorde door versus waar clausules. De volgorde per clausule moet vóór de waar-clausule verschijnen. De order by clause moet na de van - of toevoegingsclausule verschijnen. De groep per clausule moet dezelfde syntaxispositioneringsregels volgen als de volgorde door. De volgorde per clausule moet na de waar-clausule verschijnen. De waar-clausule moet na de van- of toevoegingsclausule staan. In zowel X++ als ANSI SQL moeten de from - en join-clausules vóór de order by en where-clausules verschijnen.
Condition negation. Het uitroepteken ('!') wordt gebruikt voor ontkenning. Het trefwoord niet wordt gebruikt voor ontkenning. X++ ondersteunt de syntaxis !like niet. In plaats daarvan moet u de ! operator naar een clausule.
Jokertekens voor de operator die hetzelfde doet. 0 tot veel – Sterretje ('*')
Precies 1 – Vraagteken ('?')
0 tot veel – Procentteken ('%')
Precies 1 – Onderbar ('_')
Logische operatoren in de waar-clausule . En – &&
Ofwel – ||
En – en
Of – of

Code Example

In het volgende codevoorbeeld worden de functies in de vorige tabel geïllustreerd.

static void OByWhere452Job(Args _args)
{
    // Declare the table buffer variable.
    CustTable tCustTable;
    ;
    while
    SELECT * from tCustTable
        order by tCustTable.AccountNum desc
        where (!(tCustTable.Name like '*i*i*') &amp;&amp; tCustTable.Name like 'T?e *')
    {
        info(tCustTable.AccountNum + " , " + tCustTable.Name);
    }
}
/*** InfoLog output
Message (04:02:29 pm)
4010 , The Lamp Shop
4008 , The Warehouse
4001 , The Bulb
***/

X++ SQL-trefwoorden

De volgende X++ SQL-trefwoorden behoren tot de trefwoorden die geen deel uitmaken van ANSI SQL:

  • crosscompany
  • firstonly100
  • forceliterals
  • forcenestedloop
  • forceplaceholders
  • forceselectorder
  • validtimestate

Join Clause

In de volgende tabel worden de verschillen weergegeven met betrekking tot het join-trefwoord van X++ SQL en ANSI SQL.

Feature X++ SQL ANSI SQL Comments
Columns list. De kolommen in de lijst met kolommen moeten allemaal afkomstig zijn uit de tabel die wordt vermeld in de van-clausule , en niet uit een tabel in een join-clausule . Kolommen in de lijst kunnen niet worden gekwalificeerd op basis van hun tabelnaam. De kolommen in de lijst met kolommen kunnen afkomstig zijn uit elke tabel in de van- of join-clausules. Het helpt anderen om uw code te onderhouden wanneer u de kolommen in de lijst kwalificeert met hun tabelnaam. Zie Overzichten op velden selecteren voor meer informatie.
Syntaxis van de join-clausule . De samenvoegingsclausule volgt op de waar-clausule . De samenvoegingsclausule volgt een tabel in de van-clausule . In het voorbeeld van de X++-code is het join-criterium een gelijkheid van SalesPoolId waarden.
Inner keyword. De standaard join-modus is inner join. Er is geen innerlijk trefwoord. De standaard join-modus is inner join. Het interne trefwoord is beschikbaar om de code expliciet te maken. Het buitenste sleutelwoord bestaat in zowel X++ SQL als ANSI SQL.
Links en rechts trefwoorden. De trefwoorden links en rechts zijn niet beschikbaar. Alle joins zijn links. De linker- en rechtertrefwoorden zijn beschikbaar om het join-trefwoord te wijzigen. No comments.
Equality operator. De operator met dubbele gelijkteken ('==') wordt gebruikt om de gelijkheid van twee waarden te testen. De operator met één gelijkteken ('=') wordt gebruikt om de gelijkheid van twee waarden te testen. No comments.

Code Example

In het volgende codevoorbeeld ziet u de join-syntaxis in X++ SQL.

static void OByWhere453Job(Args _args)
{
    // Declare table buffer variables.
    CustTable tCustTable;
    SalesPool tSalesPool;
    ;
    while
    SELECT
            // Not allowed to qualify by table buffer.
            // These fields must be from the table
            // in the from clause.
            AccountNum,
            Name
        from tCustTable
            order by tCustTable.AccountNum desc
            where (tCustTable.Name like 'The *')
        join tSalesPool
            where tCustTable.SalesPoolId == tSalesPool.SalesPoolId
    {
        info(tCustTable.AccountNum + " , " + tCustTable.Name);
    }
}

Aggregate Fields

In de volgende tabel worden enkele verschillen weergegeven in de manier waarop naar geaggregeerde velden in de lijst met geselecteerde kolommen wordt verwezen tussen X++ SQL en ANSI SQL. Aggregatievelden zijn velden die worden afgeleid door functies zoals som of gemiddeld.

Feature X++ SQL ANSI SQL Comments
Aggregatie van veldnaam alias. De geaggregeerde waarde staat in het veld dat is geaggregeerd. U kunt het trefwoord als gebruiken om een aggregatieveld te taggen met een naamalias. Er kan naar de alias worden verwezen in de volgende code. Zie Statistische functies: verschillen tussen X++ en SQL voor meer informatie

Code Example

In het volgende codevoorbeeld illustreert de methode aanroep naar de info de manier waarop naar geaggregeerde velden kan worden verwezen (zie tPurchLine.QtyOrdered).

static void Null673Job(Args _args)
{
    PurchLine tPurchLine;
    ;
    while
    select
        // This aggregate field cannot be assigned an alias name.
        sum(QtyOrdered)
        from tPurchLine
    {
        info(
            // QtyOrdered is used to reference the sum.
            "QtyOrdered:  " + num2str(tPurchLine.QtyOrdered, 
            3,  // Minimum number of output characters.
            2,  // Required number of decimal places in the output.
            1,  // '.'  Separator to mark the start of the decimal places.
            2   // ','  The thousands separator.
            ));
    }
    info("End.");
}
/***
Message (12:23:08 pm)
QtyOrdered:  261,550.00
End.
***/

Other Differences

In de volgende tabel worden andere verschillen van de select-instructie tussen de X++ SQL en ANSI SQL weergegeven.

Feature X++ SQL ANSI SQL Comments
Het hebben van trefwoord. Er is geen trefwoord . Met het trefwoord having kunt u filtercriteria opgeven voor rijen die worden gegenereerd door de groep op component. No comments.
Null results. Als de where-component in een tijdje select-instructie alle rijen uitfiltert, wordt er geen speciale telrij geretourneerd om dat te rapporteren. Als in een select de where-component alle rijen uitfiltert, wordt een speciale telrij geretourneerd. De telwaarde is 0. No comments.
Cursors voor het navigeren in geretourneerde rijen. De while select-instructie biedt cursorfunctionaliteit. Het alternatief is om het volgende trefwoord te gebruiken. U kunt een cursor declareren voor het doorlopen van de rijen die worden geretourneerd door een geselecteerde instructie.
From clause. Het trefwoord van is optioneel als er geen kolommen worden weergegeven en er naar slechts naar één tabel wordt verwezen. De volgende twee syntaxisopties zijn equivalent:
select \* from tCustTable;
select tCustTable;
Een select-instructie kan niet uit een tabel worden gelezen, tenzij de from-clausule wordt gebruikt. In X++ SQL vult de eenvoudige select-instructie de tabelbuffervariabele met de eerste rij die is geretourneerd. Dit wordt geïllustreerd door het volgende codefragment:
select \* from tCustTable;
info(tCustTable.Name);