Sdílet prostřednictvím


Porovnání X++ a C#

Poznámka:

Skupiny zájmu komunity se teď přesunuly z Yammeru na Microsoft Viva Engage. Pokud se chcete připojit k komunitě Viva Engage a účastnit se nejnovějších diskuzí, vyplňte formulář Žádost o přístup k aplikaci Finance and Operations Viva Engage Community a zvolte komunitu, ke které se chcete připojit.

Tento článek porovnává syntaxi a programování X++ a C#.

Porovnání X++, C#: Hello World

Tato část porovnává nejjednodušší program X++ s jeho protějškem v jazyce C#.

Porovnání X++ až C#

Následující části popisují některé základní podobnosti a rozdíly mezi X++ a C#.

Podobnosti

Následující funkce X++ jsou stejné pro jazyk C#:

  • Jednořádkové (//) a víceřádkové (/* */) komentáře.
  • == Operátor rovná se pro určení, zda jsou dvě hodnoty rovny.
  • != operátor (nerovná se) pro určení, zda dvě hodnoty nejsou ekvivalentní.
  • + Operátor (znaménko plus) pro zřetězení řetězců

Differences

Následující tabulka uvádí funkce X++, které se v jazyce C# liší.

Vlastnost X++ jazyk C# Comments
if a else podmíněné příkazy Příkaz if přijímá jakýkoli typ výrazu, který může automaticky převést na logickou hodnotu. Mezi běžné příklady patří hodnota int 0, která znamená false, nebo objekt, pro který hodnota null znamená false. Příkaz if vyžaduje logický výraz. Struktura syntaxe týkající se složených závorek a závorek je přesně stejná mezi X++ a C#.
Literální řetězec Literálový řetězec lze oddělovat některou z následujících metod:
  • Dvojice dvojitých uvozovek (") znaků.
  • Pár jednoduchých uvozovek (') znaků.
Literálový řetězec musí být oddělený dvojicí znaků dvojitých uvozovek ("). U X++ se znaky dvojitých uvozovek obvykle používají k oddělovači řetězců. Je ale vhodné řetězec oddělovat jednoduchými uvozovkami, když řetězec musí obsahovat znak uvozovek.
uklízečka type X++ neobsahuje char znakový typ ani žádný znak. Můžete deklarovat délku str jedné, ale stále se jedná o řetězec:
str 1 myString = "a";
V C# je nějaká char . Jako parametr nelze předat metodě, která zadává charstring parametr, ačkoli můžete nejprve explicitně převést char na string. Další informace o datových typech X++ naleznete v tématu Primitivní datové typy.
Výstup zpráv X++ doručuje zprávy uživateli v okně informačního protokolu. Mezi běžné metody patří:
  • Příkaz print :
  • statické metody ve Global třídě:
    • Global::info
    • Global::warning
    • Global::error
V případě programu příkazového řádku lze zprávy doručovat do konzoly. Mezi běžné metody patří:
  • Console.Out.WriteLine
  • Console.Error.WriteLine

Ukázky X++ a C#

Tato část obsahuje dvě jednoduché ukázky kódu. Jedna ukázka je napsaná v X++ a druhá je v jazyce C#. Oba vzorky dosáhnou stejného výsledku. Demonstrují se následující funkce X++:

  • // jednořádkový komentář
  • /\* \*/ víceřádkový komentář
  • Prohlášení if
  • == operátor
  • != operátor
  • + operátor pro zřetězení řetězců
  • Global::info pro výstup zprávy s předponou Global:: a bez
  • Global::error pro výstup zprávy
  • Použití jednoduchých a dvojitých uvozovek (' a ") jako oddělovačů řetězců.

Poznámka:

Osvědčeným postupem je použít dvojité uvozovky pro libovolný řetězec, který se může uživateli zobrazit.

Ukázka X++

Tento vzorový kód X++ je ve formě úlohy. Ve stromu objektů aplikace (AOT) je uzel s názvem Úlohy. Tuto ukázku je možné přidat do uzlu Úlohy a pak lze úlohu spustit.

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.");
    }
}
Výstup

Tady je výstup z okna informačního protokolu: Zpráva (09:49:48) Hello World, 1. Hello World, 2. To se podobá informacím, ale platí pro upozornění, 3. To se podobá informacím, ale jsou to chyby 4.

Ukázka jazyka C#

Následující program jazyka C# je přepsáním předchozího programu X++.

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.");
        }
    }
}
Výstup

Zde je skutečný výstup konzoly jazyka C#:

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.

Porovnání X++, C#: Smyčky

Tato část porovnává funkce smyčky mezi X++ a C#.

Podobnosti

V X++ a C# jsou stejné následující funkce:

  • Deklarace pro proměnné primitivního datového typu int. Deklarace jiných primitivních typů jsou téměř stejné, ale typy mohou mít různé názvy.
  • while – příkaz pro smyčky.
  • příkaz break pro ukončení smyčky.
  • příkaz continue přejde nahoru na začátek smyčky.
  • <= (menší nebo rovno) relační operátor.

Differences

Následující tabulka uvádí funkce X++, které se v jazyce C# liší.

Features X++ jazyk C# Comments
Příkaz for . Příkaz for je k dispozici pro smyčky. Příkaz jazyka C# for se mírně liší od for příkazu X++. V jazyce C# můžete deklarovat celé číslo čítače for v příkazu. V X++ však musí být čítač deklarován mimo for příkaz.
++ inkrementačního operátoru. Operátor přírůstku ++ je k dispozici v X++. Ale int proměnná, která je zdobena ++ lze použít pouze jako příkaz, ne jako výraz. Například následující řádky kódu X++ by se nezkompilovaly:
int age=42;
print age++;
Následující řádky kódu X++ by se však zkompilovaly:
int age=42;
age++; print age;
Operátor C# ++ je flexibilnější než v X++. Následující řádky kódu jsou v obou jazycích stejné:
  • ++ myInteger;
  • myInteger++;
Následující řádky kódu se ale liší od sebe a jsou platné pouze v jazyce C#:
  • yourInt = ++myInt;
  • yourInt = myInt++;
modulo – operátor. V X++ je operátor modulo mod. V jazyce C# je operátor modulo %. Symboly operátoru modulo se liší, ale jejich chování je v obou jazycích stejné.
Dočasně pozastaví konzolovou aplikaci, která již začala. Příkaz pause . V jazyce C# je možné program příkazového řádku pozastavit následujícím řádkem kódu:
Console.In.Read();
V X++ pokračujte kliknutím na tlačítko OK v modálním dialogovém okně. V jazyce C# pokračujte stisknutím libovolné klávesnice na klávesnici.
Zobrazí zprávu. V X++ příkaz print zobrazí zprávu v okně Print. V jazyce C# lze zprávu zobrazit v konzole pomocí následujícího řádku kódu:
Console.WriteLine();
Funkce X++ print se používá pouze při testování. Program X++, který používá print téměř vždy pause příkaz někde později v kódu. Pro produkční kód X++ použijte místo metody Global::info .print Funkce strfmt se často používá společně s info. Neexistuje důvod k použití pause po info.
Udělej zvuk. Funkce pípnutí provede zvuk, který uslyšíte. V jazyce C# je zvuk, který uslyšíte, vydán následujícím řádkem kódu:
Console.Beep();
Každý příkaz vytvoří krátký tón.

Ukázky kódu X++ pro smyčky používají print funkci k zobrazení výsledků. V jazyce X++ můžete příkaz zobrazit print libovolný primitivní datový typ, aniž byste museli volat funkce, které je nejprve převedou na řetězec. To je print užitečné v rychlých testovacích situacích. Obecně platí, že metoda Global::info se používá častěji než print. Metoda info může zobrazovat pouze řetězce. Proto se funkce strfmt často používá společně s info. Omezení print spočívá v tom, že obsah okna Tisk nejde zkopírovat do schránky (například ctrl+C). Global::info zapisuje do okna informačního protokolu, které podporuje kopírování do schránky.

Příklad 1: Smyčka while

Klíčové slovo while podporuje smyčky v X++ i C#.

Ukázka X++ while

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.
} 
Výstup

Výstup v okně Tisk V X++ je následující:

1
2
3
4

Ukázka jazyka C# 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();
    }
}
Výstup

Výstup konzoly z programu V# je následující:

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

Příklad 2: Smyčka for

Klíčové slovo for podporuje smyčky v X++ i C#.

Ukázka X++ pro

V X++ nelze proměnnou čítače deklarovat jako součást příkazu for .

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;
}
Výstup

Výstup v okně Tisk V X++ je následující:

1
2
3
4

Ukázka jazyka C# pro

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();
    }
}
Výstup

Výstup konzoly z programu V# je následující:

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.)

Porovnání X++, C#: Switch

V X++ i C# příkaz switch zahrnuje velká a malá písmena, přerušení a výchozí. Následující tabulka uvádí rozdíly v příkazu switch mezi X++ a C#.

Vlastnost X++ jazyk C# Comments
break; na konci každého bloku případu V X++ platí, že pokud libovolný blok případu odpovídá hodnotě výrazu v klauzuli switch , všechny ostatní bloky avýchozí bloky se spustí, dokud break; se nedosáhne příkazu. V příkazu break; X++ se nikdy nevyžaduje žádný příkaz, ale break; příkazy jsou důležité téměř ve všech praktických situacích. V jazyce C# break; je příkaz vždy potřeba po příkazech v případě nebo výchozím bloku. Pokud klauzule case neobsahuje žádné příkazy mezi sebou a další klauzulí case , break; není mezi těmito dvěma klauzulemi case vyžadován příkaz. Doporučujeme vynechat break; příkaz po jakémkoli bloku případu, protože může zmást další programátora, který upravuje kód.
break; na konci výchozího bloku V jazyce X++ nemá vliv na přidání break; příkazu na konec výchozího bloku. V jazyce C# kompilátor vyžaduje break; příkaz na konci výchozího bloku. Další informace naleznete v tématu Switch – příkazy.
Pouze konstantní hodnoty bloku případu V X++ můžete zadat literálovou hodnotu nebo proměnnou v bloku případu. Můžete například napsat případ myInteger:. V jazyce C# je nutné zadat přesně jednu hodnotu literálu pro každý blok případu a nejsou povoleny žádné proměnné. Žádné komentáře.
Více hodnot v jednom bloku případu V X++ můžete zadat více hodnot v každém bloku případu. Hodnoty musí být oddělené čárkou. Můžete například napsat case 4,5,myInteger:. V jazyce C# musíte pro každý blok případu zadat přesně jednu hodnotu. V X++ je lepší napsat více hodnot na jeden blok případu , než vynechat break; příkaz na konci jednoho nebo více bloků případů.

Příklady kódu pro přepínač

Následující části ukazují srovnatelné příkazy switch v X++ a C#.

Příklad přepínače X++

Příklad přepínače X++ ukazuje následující:

  • case iTemp: a case (93-90): zobrazit, že výrazy velkých a malých písmen nejsou omezeny na konstanty, protože jsou v jazyce C#.
  • //break; k zobrazení, že break; příkazy nejsou v X++ povinné, i když jsou téměř vždy žádoucí.
  • case 2, (93-90), 5: chcete-li zobrazit, že více výrazů může být uvedeno v jedné klauzuli case v 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
***

Příklad přepínače jazyka C#

Příklad přepínače jazyka C#ukazuje následující:

  • případ 1: obsahuje komentář vysvětlující, že klauzuli case může obsahovat pouze konstantní výrazy.
  • break; příkazy se vyskytují po posledním příkazu v každém bloku případu , který obsahuje příkazy, jak to vyžaduje jazyk 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
>>
***/

Porovnání X++, C#: Velká a velká písmena řetězců

Tato část porovnává zacházení s řetězci se smíšeným písmenem v X++ a C#. Vysvětluje také oddělovače řetězců, které jsou k dispozici v X++.

Podobnosti

Následující funkce X++ jsou stejné jako v jazyce C#:

  • Zpětné lomítko (\) je řídicí operátor pro oddělovače řetězců.
  • Znak at (@) nullifuje řídicí efekt zpětného lomítka při zápisu znaku při znaménku bezprostředně před otevřenou uvozovku řetězce.
  • Znaménko plus (+) je operátor zřetězení řetězce.

Differences

Funkce X++, které se v jazyce C# liší, jsou uvedeny v následující tabulce.

Vlastnost X++ jazyk C# Comments
== operátor porovnání Nerozlišuje se: == operátor nerozlišuje rozdíly v velikostech řetězců. V jazyce C# == je operátor citlivý na rozdíly v písmenech řetězců. V jazyce X++ můžete použít funkci strCmp pro porovnání s rozlišováním malých a velkých písmen mezi řetězci.
Oddělovače řetězců V X++ můžete jako oddělovač řetězců použít jednoduchou (') nebo dvojitou (") uvozovku.

Poznámka: Osvědčeným postupem je obvykle použít dvojité uvozovky pro řetězce, které se můžou uživateli zobrazit. Je ale vhodné označit řetězec jednoduchými uvozovkami, pokud je jedním ze znaků v řetězci jeden z znaků.

V jazyce C# musíte jako oddělovač řetězců použít dvojitou uvozovku. To odkazuje na typ System.String. V X++ a C# máte možnost vložit oddělovač do literálového řetězce a vysoupat ho pomocí .
V X++ máte také alternativu vložení jednoduchých uvozovek do řetězce, který je oddělený dvojitými uvozovkami (nebo obráceně), aniž byste museli použít řídicí znak.
Oddělovače znaků X++ má datový typ řetězce (str), ale žádný typ znaku. V jazyce C# musíte jako oddělovač znaků použít jednoduchou uvozovku. To odkazuje na typ System.Char. V rozhraní .NET Framework System.String je délka jiného datového System.Char typu než znak.

Příklad 1: Citlivost malých a velkých písmen operátoru ==

Operátory == a != nerozlišují velká a malá písmena v jazyce X++, ale rozlišují velká a malá písmena v jazyce C#, jak je znázorněno v následujícím příkladu.

X++ jazyk C# Comments
"HELLO" == "hello"
True v X++.
"HELLO" == "hello"
False v jazyce C#.
Různá porovnání případů mezi X++ a C#.

Příklad 2: Operátor zřetězení + řetězec

Operátory + a += slouží ke zřetězení řetězců v X++ i C#, jak je znázorněno příklady v následující tabulce.

X++ jazyk C# Comments
myString1 = "Hello" + " world";
Výsledek je rovnost:
myString1 == "Hello world"
(Stejné jako pro X++.) V X++ i C# závisí chování operátoru + na datovém typu jeho operandů. Operátor zřetězí řetězce nebo sčítá čísla.
mystring2 = "Hello";
myString2 += " world";
Výsledek je rovnost: myString2 == "Hello world"
(Stejné jako pro X++.) V X++ i C# jsou následující příkazy ekvivalentní:
a = a + b;
a += b;

Příklad 3: Vkládání a escaping string delimiters

Jednoduché nebo dvojité uvozovky lze použít k oddělovači řetězců v X++. Řídicí znak (\) lze použít k vložení oddělovačů do řetězce. Ty jsou znázorněny v následující tabulce.

X++ jazyk C# Comments
myString1 = "They said \"yes\".";
Výsledek:
They said "yes".
(Stejné jako pro X++.) Řídicí znak umožňuje vložit oddělovače řetězců do řetězců.
myString2 = 'They said "yes".';
Výsledek:
They said "yes".
Syntaxe jazyka C# neumožňuje oddělovat řetězce jednoduchými uvozovkami. U řetězců, které může uživatel vidět, se považuje za osvědčený postup použití řídicího znaku místo jednoduchých uvozovek, jak je znázorněno v příkladu.
myString3 = "They said 'yes'.";
Výsledek:
They said 'yes'.
(Stejné jako pro X++.) V jazyce X++ nejsou jednoduché uvozovky považovány za oddělovače, pokud řetězec nezačíná oddělovačem jednoduchých uvozovek. V jazyce C# nemá jednoduché uvozovky žádný zvláštní význam pro řetězce a nelze ho použít k oddělovači řetězců. V jazyce C# je povinným oddělovačem pro literály typu System.Char. X++ nemá žádný datový typ znaku.
str myString4 = 'C';
V této jednoduché uvozovce je oddělovač řetězců.
char myChar4 = 'C';
Zde je System.Char jednoduchý uvozovka oddělovač, nikoli System.String oddělovač.
X++ nemá žádný datový typ, který odpovídá System.Char v rozhraní .NET Framework. Řetězec X++, který je omezen na délku jednoho, je stále řetězec, nikoli datový typ znaku.

Příklad 4: Jeden řídicí znak

Příklady, které ilustrují jeden řídicí znak ve vstupu nebo výstupu, jsou uvedeny v následující tabulce.

X++ jazyk C# Comments
myString1 = "Red\ shoe";
Výsledek:
Red shoe
Literálový řetězec v jazyce C# nemůže obsahovat dvě sekvence znaků řídicího znaku následovanou mezerou, například \. Dojde k chybě kompilátoru. Když kompilátor X++ narazí na dvě znakové sekvence "\ ", zahodí jeden řídicí znak.
myString2 = "Red\\ shoe";
Výsledek:
Red\ shoe
(Stejné jako pro X++.) Ve dvojici řídicích znaků první neguje zvláštní význam druhého.

Porovnání: Syntaxe pole

Existují podobnosti a rozdíly v funkcích a syntaxi polí v X++ a C#.

Podobnosti

Celkově je v syntaxi a léčbě polí v X++ a C# hodně podobnosti. Existuje však mnoho rozdílů.

Differences

Následující tabulka uvádí oblasti v syntaxi [] pro pole, která se liší pro X++ a C#.

Kategorie X++ jazyk C# Comments
Prohlášení Pole je deklarováno pomocí hranatých závorek připojených k názvu proměnné. Pole je deklarováno pomocí hranatých závorek připojených k datovému typu. int myInts[]; // X++

Poznámka: Pole X++ nemůže být parametrem v metodě.

int[] myInts; // C#

Prohlášení Syntaxe pole podporuje pouze primitivní datové typy, například int a str. Syntaxe nepodporuje třídy ani tabulky. Syntaxe pole podporuje primitivní datové typy a třídy. V X++ můžete použít Array Pole pro pole objektů.
Prohlášení X++ je omezen na pole s jednou dimenzí (myStrings[8]). Jazyk C# přidává podporu multidimenzionálních polí (myStrings[8;3]) a pro žloutnutá pole (myStrings[8][3]). V X++ nemůžete mít pole polí. Existuje však pokročilá syntaxe pro omezení množství aktivní paměti, kterou může velké pole využívat, což vypadá jako multidimenzionální syntaxe v jazyce C#: int intArray[1024;16];. Další informace najdete v tématu Optimalizace výkonu osvědčených postupů: Prohození polí na disk.
Prohlášení V X++ je pole speciální konstruktor, ale není to objekt. V jazyce C# jsou všechny pole objekty bez ohledu na varianty syntaxe. X++ má třídu Array, ale jeho základní mechanismus se liší od polí vytvořených pomocí syntaxe []. Ve všech polích jazyka C# se používá stejný základní mechanismus bez ohledu na to, jestli se v kódu používá syntaxe System.Array třídy [].
Délka V X++ je délka pole statické velikosti určena v syntaxi deklarace. V jazyce C# je velikost pole určena při vytvoření objektu pole. Pokud použijete syntaxi deklarace [] v X++, není před přiřazením hodnot k poli potřeba žádná další příprava.
V jazyce C# musíte deklarovat a potom před přiřazením k němu sestavit pole.
Délka Pole X++ může mít dynamickou délku, kterou lze zvýšit i po zahájení populace. To platí pouze v případě, že je pole deklarováno bez čísla uvnitř []. Pokud se délka dynamického pole často zvyšuje, může být výkon zpomalován. V jazyce C# nelze po nastavení délky změnit délku pole. V následujícím fragmentu kódu X++ je pouze myInts pole dynamické a může se zvětšit.
int myInts[];
int myBools[5];
myInts[2] = 12;
myInts[3] = 13;
myBools[6] = 26; //Error
Délka Délku některých polí můžete získat pomocí dimOf funkce. Pole jazyka C# jsou objekty, které mají Length vlastnost. Žádné komentáře.
Indexování Indexování pole je založené na 1. Indexování pole je založené na 0. mtIntArray[0] způsobí chybu v X++.
Konstanta V X++ je nejlepší dosáhnout konstantní hodnoty pomocí #define direktivy precompiler. V jazyce C# můžete deklaraci proměnné vyzdobit pomocí klíčového slova const, abyste dosáhli konstantní hodnoty. X++ nemá klíčové slovo const . Jazyk C# nemůže přiřadit hodnoty proměnným vytvořeným direktivou prekompileru #define.

Ukázky X++ a C#

Následující ukázky kódu ukazují, jak se zpracovávají pole primitivních datových typů. První ukázka je v X++ a druhá ukázka je v jazyce C#. Obě ukázky dosáhnou stejných výsledků.

Ukázka X++

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]));
    }
}
Výstup

Výstup do informačního protokolu je následující:

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

Ukázka jazyka C#

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
Výstup

Výstup z programu C# do konzoly příkazového řádku je následující:

-------- 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]

Další funkce X++ podobné poli

Kontejner je speciální datový typ, který je k dispozici v X++. Lze ji považovat za podobnou matici nebo podobné kolekci List .

Porovnání: Kolekce

V aplikaci pro finance a operace můžete použít třídu kolekce X++ List . Rozhraní .NET Framework, které se používá v jazyce C#, má podobnou třídu s názvem System.Collections.Generic.List.

Porovnání použití tříd seznamů

Následující tabulka porovnává metody třídy X++ List s metodami z System.Collections.Generic.List rozhraní .NET Framework a jazyka C#.

Vlastnost X++ jazyk C# Comments
Deklarace kolekce List myList; List<string> myList; Deklarace X++ neobsahuje typ elementů, které se mají uložit.
Deklarace iterátoru ListIterator iter
ListEnumerator enumer;
IEnumerator<string> iter; V X++ ListIterator objekt má metody, které mohou insert a delete položky z objektu List. X++ ListEnumerator nemůže změnit obsah Listsouboru . V X++ ListEnumerator objekt je vždy vytvořen na stejné úrovni jako List. To není vždy pravdivé pro ListIterator.
Získání iterátoru new ListIterator (myList)
myList.getEnumerator()
myList.GetEnumerator() V X++ i C# objekt List má metodu getter pro přidružený enumerátor.
Konstruktor new List(Types::String) new List<string>() Informace o typu objektů, které mají být uloženy uvnitř List tříd, jsou předány konstruktoru v X++ i C#.
Aktualizace dat Enumerátor – enumerátor se stane neplatným, pokud jsou přidány nebo odebrány některé položky v objektu List .
Iterátor – iterátor obsahuje metody, které vkládají a odstraňuje položky z objektu List. Iterátor zůstane platný.
Enumerátor – enumerátor se stane neplatným, pokud jsou přidány nebo odebrány některé položky v objektu List . Enumerátory se po přidání nebo odstranění položek z jazyka ListX++ a C# stanou neplatnými.
Aktualizace dat V X++ List třída obsahuje metody pro přidání položek na začátku nebo konci seznamu. V jazyce C# List třída obsahuje metody pro přidávání členů na libovolné pozici v seznamu. Obsahuje také metody pro odebrání položek z libovolné pozice. V položkách X++ je možné odebrat List pouze iterátorem.

Příklad 1: Deklarace seznamu

Následující příklady kódu jsou v X++ a C#, které deklarují List kolekce.

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

Příklad 2: Konstrukce seznamu

V obou jazycích musí být typ položek, které úložiště kolekce musí být zadán v době výstavby. U typů tříd X++ nemůže získat více konkrétnější než to, zda je typ třídou (Types::Class). Následující příklady kódu jsou v X++ a C#.

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

Příklad 3: Přidání položek do seznamu

V X++ i C# poskytuje kolekce metodu pro připojení položky na konec kolekce a pro vložení položky na začátek. V jazyce C# kolekce poskytuje metodu pro vložení v libovolném bodě v kolekci na základě hodnoty indexu. V X++ může iterátor kolekce vložit položku na aktuální pozici. Následující příklady kódu jsou v X++ a 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");

Příklad 4: Iterace seznamu

X++ i C# mají třídy iterátoru, které můžete použít k procházení položek v kolekci, jak je znázorněno v následujících příkladech.

// 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); 
}

Příklad 4b: foreach v jazyce C#

V jazyce C# se klíčové slovo foreach často používá ke zjednodušení iterace prostřednictvím seznamu. Následující příklad kódu se chová stejně jako předchozí příklad jazyka C#.

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

Příklad 5: Odstranění druhé položky

Následující příklady kódu odstraní druhou položku z kolekce. V X++ to vyžaduje iterátor. V jazyce C# samotná kolekce poskytuje metodu pro odebrání položky.

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

Příklad 6: Kombinování dvou kolekcí

Následující příklady kódu kombinují obsah dvou kolekcí do jedné.

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

Porovnání: Kolekce klíčů s hodnotami

V aplikaci pro finance a provoz můžete použít Map třídu kolekce. Kolekce Map obsahuje páry hodnot, hodnotu klíče a datovou hodnotu. Podobá se tomu třída rozhraní .NET Framework s názvem System.Collections.Generic.Dictionary.

Podobnosti

Následující seznam popisuje podobnosti mezi X++ a C# týkajícími se kolekcí, které ukládají páry klíč-hodnota:

  • Oba brání duplicitním klíčům.
  • Oba používají enumerátor (nebo iterátor) k procházení položek.
  • Oba objekty kolekce klíč-hodnota jsou tvořeny označeními typů, které jsou uloženy jako klíč a hodnota.
  • Oba můžou ukládat objekty třídy a nejsou omezené na ukládání primitiv, jako je int.

Differences

Následující tabulka popisuje rozdíly mezi X++ a C# týkajícími se tříd kolekcí, které ukládají páry klíč-hodnota:

Vlastnost X++ jazyk C# Comments
Duplicitní klíče V X++ Map třída zabraňuje duplicitním klíčům tím, že implicitně zachází s voláním své insert metody jako s operací, aby se aktualizovala pouze hodnota přidružená ke klíči. V jazyce C# Dictionary třída vyvolá výjimku při pokusu o přidání duplicitního klíče. Duplicitní klíče jsou v obou jazycích zabráněné, i když různé techniky.
Odstranění položek V X++ delete metoda u objektu iterátoru slouží k odebrání nežádoucí dvojice klíč-hodnota z objektu Map. V jazyce C# Dictionary má třída metodu remove . V obou jazycích je enumerátor neplatný, pokud je počet položek kolekce změněn během životnosti enumerátoru.

Příklad 1: Deklarace kolekce Key-Value

V obou jazycích musí být zadán typ položek, které jsou v úložišti kolekce klíč-hodnota. V X++ je typ zadán v době konstrukce. V jazyce C# je typ zadán v době deklarace i v době výstavby. Následující příklady kódu jsou v X++ a C#.

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

Příklad 2: Konstrukce kolekce

V obou jazycích typ položek, které kolekce klíč-hodnota ukládá během sestavování. U typů tříd X++ nemůže získat více konkrétnější než to, zda je typ třídou (Types::Class). Následující příklady kódu jsou v X++ a C#.

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

Příklad 3: Přidání položky do kolekce

V X++ a C# se téměř neliší způsob přidání položky do kolekce klíč-hodnota, jak je znázorněno v následujících příkladech kódu.

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

Příklad 4: Iterace prostřednictvím kolekce Key-Value

Enumerátory se používají ke smyčce kolekcí klíč-hodnota v X++ i C#, jak je znázorněno v následujících příkladech kódu.

// 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.
}

Příklad 5: Aktualizace hodnoty přidružené ke klíči

Syntaxe se mezi těmito dvěma jazyky velmi liší pro aktualizaci hodnoty přidružené k danému klíči. Následující příklady kódu jsou určené pro klíč 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.”;

Příklad 6: Odstranění jedné položky

Syntaxe se mezi těmito dvěma jazyky velmi liší, aby se odstranil jeden pár klíč-hodnota z kolekce, zatímco iterace prostřednictvím členů kolekce. Příklady kódu pro klíč 102 jsou uvedeny níže.

// 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);

Porovnání: Výjimky

Existuje několik podobností, ale mnoho rozdílů, když porovnáváme chování související s výjimkami mezi X++ a C#. Klíčová slova try, catch a throw se chovají stejně v X++ a C#. Typy vyvolaných a zachycených výjimek se ale u těchto dvou jazyků liší.

Podobnosti

Podobnosti mezi X++ a C# týkajícími se jejich funkcí výjimek zahrnují následující příklady:

  • Oba jazyky mají stejné klíčové slovo try .
  • Oba mají stejné klíčové slovo catch .
  • Oba umožňují příkaz catch , který neurčí žádnou konkrétní výjimku. Takový příkaz catch zachytí všechny výjimky, které se k němu dostanou.
  • Oba mají stejné klíčové slovo throw .

Differences

Rozdíly související s výjimkami mezi X++ a C# jsou popsány v následující tabulce.

Vlastnost X++ jazyk C# Comments
zkusit ještě jednou Přeskočí na první instrukci v přidruženém bloku try . Další informace najdete v tématu Zpracování výjimek pomocí klíčových slov try a catch. Funkce klíčového slova opakování je možné mimickovat v kódu jazyka C#, ale neexistuje odpovídající klíčové slovo. Pouze X++ má klíčové slovo pro opakování . Jazyk C# nemá žádný protějšek. Další informace najdete v tématu X++, porovnání jazyka C#: Automatizované opakování po výjimce.
nakonec Klíčové finally slovo je podporováno pro sledování try klíčových slov a catch klíčových slov. Nakonec klíčové slovo označuje blok kódu, který následuje za bloky try a catch. Nakonec se spustí bez ohledu na to, jestli je vyvolána nebo zachycena jakákoli výjimka. Sémantika je stejná jako sémantika v jazyce C#.
Konkrétní výjimky V X++ je výjimka prvek výčtu Exception , například Error, Deadlock nebo CodeAccessSecurity. Žádná výjimka nemůže obsahovat jinou. V jazyce C# je výjimka instance System.Exception základní třídy nebo jakékoli třídy, která z ní dědí. Výjimka může být obsažena ve InnerException vlastnosti vyvolané výjimky. V X++ každá vyvolaná výjimka je hodnota výčtu Exception. Další informace naleznete v tématu Výčtu výjimek.
Zpráva o výjimce V X++ zpráva vytvořená při vyvolání výjimky je k dispozici pouze v informačním protokolu a zpráva není přímo svázána s výjimkou. V jazyce C# je Message zpráva členem objektu System.Exception . V X++ Metoda Global::error je mechanismus, který zobrazuje zprávy o výjimce v informačním protokolu. Další informace najdete v tématu Zpracování výjimek pomocí klíčových slov try a catch.
Podmínky výjimky V X++ dojde k chybě, když zavoláte metodu instance u proměnné objektu, která ještě neměla přiřazené nic. Kromě této chyby však není vyvolána žádná výjimka. Proto žádný catch blok nemůže získat kontrolu, i když je nepřiřazená proměnná v bloku zneužita try . V následujícím příkladu kódu chyba způsobená kódem box4.toString(); nezpůsobí přenos do žádného catch bloku: DialogBox box4;try { box4.toString(); info("toString did not error, but expected an error."); } catch (Exception::Error) // Žádná hodnota výjimky to zachytí. { info("Invalid use of box4 gave control to catch, unexpected."); } V jazyce C# je System.NullReferenceException vyvolána, když je neinicializovaná proměnná považována za odkaz na objekt. V podmínkách, které vyvolávají výjimky, může existovat několik dalších rozdílů.
Transakce SQL V X++ když dojde k výjimce SQL v ttsBegin - ttsCommit transakce, nemůže žádný příkaz catch uvnitř bloku transakce zpracovat výjimku. V jazyce C# blok catch uvnitř transakce SQL může zachytit výjimku.

Examples

Demonstrují se následující funkce X++:

  • try keyword.
  • catch keyword.
  • Chování po výjimce::Error dojde k výjimce.

Příklad X++

// 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.");
}
Výstup

Tady je výstup z okna informačního protokolu:

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.

Ukázka jazyka C#

Následující program jazyka C# je přepsáním předchozího programu X++.

// 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
Výstup

Tady je výstup konzoly C#:

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

Porovnání: Automatizované opakování po výjimce

Někdy můžete napsat kód do bloku catch, který opraví příčinu výjimky, ke které dochází během běhu. X++ poskytuje klíčové slovo opakování , které lze použít pouze uvnitř bloku catch . Klíčové slovo opakování umožňuje programu přejít zpět na začátek bloku try po vyřešení problému kódem v bloku catch . Jazyk C# nemá klíčové slovo pro opakování . Kód jazyka C# však lze zapsat tak, aby poskytoval ekvivalentní chování.

Ukázky kódu pro opakování

Následující ukázkový program X++ způsobí vyvolání výjimky::Error. K tomu dochází, když se poprvé pokusí přečíst prvek z sStrings pole pomocí neplatné hodnoty indexu. Při zachycení výjimky se během doby běhu uvnitř bloku catch provede nápravná akce. Příkaz opakování se pak vrátí k prvnímu příkazu v bloku try . Tato druhá iterace funguje bez jakékoli výjimky.

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;
}

Výstup

Tady je výstup okna Tisk:

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.

Ukázka jazyka C#

Následující ukázka jazyka C# není řádkový překlad z předchozí ukázky X++. Místo toho má program jazyka C# jinou strukturu, aby napodoboval chování klíčového slova opakování , na kterém program X++ spoléhá. Bloky try a catch jsou ve volané metodě. Proměnné použité v bloku try jsou uloženy v metodě volajícího. Metoda volajícího předá proměnné jako parametry, které jsou zdobeny klíčovým slovem ref , aby jejich hodnoty mohly být opraveny uvnitř zachytávacího bloku volané metody. Volaná metoda zachycuje všechny výjimky a vrátí logickou hodnotu , která volajícímu sdělí, zda je požadováno druhé volání.

// 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;
    }
}

Výstup

Tady je výstup konzoly:

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.

Porovnání: Operátory

Tato část porovnává operátory mezi X++ a C#.

Operátory přiřazení

Následující tabulka zobrazuje rozdíly mezi operátory přiřazení v X++ a C#.

X++ a C# Differences
= V X++ tento operátor způsobí implicitní převod vždy, když dojde ke ztrátě přesnosti, například pro přiřazení z int64 na int. V jazyce C# ale přiřazení způsobí chybu kompilace.
+= a -= Jediným rozdílem je, že v jazyce C# se tyto operátory používají také při manipulaci s delegáty.
++ a -- Jedná se o operátory inkrementace a dekrementace v obou jazycích. Následující řádek je v obou jazycích stejný:
++myInteger;
V X++ jsou ale tyto dva operátory pro příkazy, ne pro výrazy. Proto následující řádky generují chyby kompilace v X++:
myStr = int2str(++myInteger);
myIntA = myIntBB++;

Aritmetické operátory

Následující tabulka uvádí aritmetické operátory.

X++ a C# Differences
* Jako operátor násobení neexistují žádné rozdíly.

Poznámka: Hvězdička se také používá v příkazech SQL, které jsou součástí jazyka X++. V těchto příkazech SQL může hvězdička být také jedním z následujících:

  • Zástupný znak označující, že by se měly vrátit všechny sloupce.
  • Zástupný znak pro znaky v řetězci, který se používá v klauzuli like .
/ Operátor dělení je stejný v X++ a C#.
MOD Jediným rozdílem v operacích modulo je, že se v jazyce C# používá symbol %.
+ Operátor sčítání je stejný v X++ a C#. Znaménko plus se používá také pro zřetězení řetězců. Tento operátor sčítá čísla a zřetězí řetězce v obou jazycích.
- Operátor odčítání je stejný v X++ a C#.

Bitové operátory

Následující tabulka porovnává bitové operátory mezi X++ a C#.

X++ a C# Differences
<< Operátor levého posunu je stejný v X++ a C#.
>> Operátor pravého posunu je stejný v X++ a C#.
~ Bitový operátor NOT je stejný v X++ a C#.
& Binární operátor AND je stejný v X++ a C#.
^ Binární operátor XOR je stejný v X++ a C#.

Relační operátory

Následující relační operátory jsou stejné v X++ a C#:

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

Porovnání: Události

Existují určité rozdíly v tom, jak X++ a C# implementují vzor návrhu událostí. Další informace naleznete v tématu Terminologie událostí a klíčová slova.

Porovnání událostí mezi X++ a C#

Existují rozdíly ve způsobu, jakým se delegáti používají pro události v X++ a C#.

Koncepce X++ jazyk C# Comments
delegate V X++ lze delegát deklarovat pouze jako člen třídy. Delegát nemůže být členem tabulky. Všichni delegáti jsou členy třídy instance, nikoli statické členy. U deklarace delegáta nelze použít žádný modifikátor přístupu, protože všichni delegáti jsou chráněni členy. Proto může být událost vyvolána pouze kódem ve stejné třídě, ve které je delegát členem. Jedinou výjimkou soukromé povahy delegáta je, že kód mimo jejich třídu může pracovat s delegáty pomocí operátorů += a -= . V jazyce C# je každý delegát typem, stejně jako každá třída je typ. Delegát je deklarován nezávisle na jakékoli třídě. Bez klíčového slova události můžete mít delegáta jako typ parametru metody, stejně jako můžete mít třídu jako typ parametru. Pro hodnotu parametru můžete vytvořit instanci delegáta, která se má předat. V X++ je každá třída typem, ale žádný delegát není typ. Nelze vytvořit instanci delegáta. Žádný delegát nemůže být parametrem pro metodu. Můžete ale vytvořit třídu, která má člena delegáta, a můžete předat instance třídy jako hodnoty parametrů. Další informace naleznete v tématu X++ Keywords.
událost V kódu X++ je událost jedním z následujících způsobů:
  • Explicitní volání delegáta.
  • Začátek nebo konec metody.
V X++ není klíčové slovo události .
V jazyce C# se klíčové slovo události používá k deklaraci typu delegáta jako člena třídy. Výsledkem klíčového slova události je nastavit delegáta jako chráněný, ale stále přístupný pro operátory += a -= . Metody obslužné rutiny události můžete přihlásit k odběru události pomocí operátoru += . Delegát může být užitečný bez klíčového slova události, jako technika pro předání ukazatele funkce jako parametru do metody. Automatické události, ke kterým dochází před zahájením metody a po ukončení metody, je možné přihlásit k odběru pouze pomocí AOT.
+= a -= – operátory V X++ použijete operátor += k odběru metod delegáta. Operátor -= odhlásí od delegáta metodu. V jazyce C# použijete operátor += k odběru metod události nebo delegáta , který se nepoužívá s klíčovým slovem události . Delegát obsahuje odkaz na všechny objekty, které mají metody odebírané delegátu. Tyto objekty nemají nárok na uvolňování paměti, zatímco delegát tyto odkazy uchovává.
eventHandler V X++ je klíčové slovo eventHandler vyžadováno, když použijete operátor += nebo -= k přihlášení k odběru nebo odhlášení metody od delegáta. System.EventHandler je typ delegáta v rozhraní .NET Framework. Tento termín se v jazyce X++ používá jinak než v jazyce C# nebo .NET Framework. Další informace naleznete v tématu X++ Keywords.

Příklad X++

Důležité věci, které je potřeba si všimnout, jsou v příkladu X++:

  • XppClass člena delegáta, který má název myDelegate.

    Poznámka:

    AOT obsahuje uzel pro delegáta. Uzel se nachází ve třídách > AOT > XppClass > myDelegate. Pod uzlem myDelegate může být umístěno několik uzlů obslužné rutiny události. Obslužné rutiny událostí reprezentované uzly v AOT nelze odebrat operátorem -= během běhu.

  • Složené {} závorky na konci deklarace delegáta jsou povinné, ale nemohou v nich mít žádný kód.

  • Obsahuje XppClass dvě metody, jejichž podpisy parametrů jsou kompatibilní s delegátem. Jedna metoda je statická.

  • Do delegáta se přidají dvě kompatibilní metody s operátorem += a klíčovým slovem eventHandler . Tyto příkazy nevolají metody obslužné rutiny události, příkazy přidávají metody pouze do delegáta.

  • Událost je vyvolána jedním voláním delegáta.

  • Hodnota parametru předaná delegátovi je přijata každou metodou obslužné rutiny události.

  • Krátká úloha X++ v horní části příkladu spustí 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);
    }
}

Výstup předchozí úlohy X++ je následující:

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.

Ukázka jazyka C#

Tato část obsahuje ukázku kódu jazyka C# pro vzor návrhu událostí předchozí ukázky X++.

// 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);
    }
}

Výstup z předchozí ukázky jazyka C# je následující:

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.

Události a AOT

Existují i jiné systémy událostí, které se vztahují pouze na položky v AOT. Další informace naleznete v tématu Uzly obslužné rutiny událostí v AOT.

Porovnání: Direktivy prekompileru

X++ a C# sdílejí některá klíčová slova pro syntaxi direktivy prekompileru, ale významy nejsou vždy stejné.

Podobnosti

Kompilátory X++ a C# rozpoznávají mnoho stejných klíčových slov. Ve většině případů znamenají klíčová slova stejné pro oba jazykové kompilátory.

Differences

Základním rozdílem mezi direktivami prekompileru v jazyce X++ a C# je klíčové slovo #define, které rozpozná oba prekompilátory jazyka. Na rozdíl od jazyka C# vyžaduje v X++ direktiva #define tečku v syntaxi. V X++ lze závorky použít k poskytnutí definovaného symbolu hodnotu. Tyto rozdíly jsou uvedeny v následujících příkladech:

  • V X++: #define. InitialYear(2003)
  • V jazyce C#: #define InitialYear

Malý rozdíl spočívá v tom, že v jazyce C# mohou být mezery a znaky tabulátoru mezi znakem # a klíčovým slovem direktivy, například # define Testing.

Identická klíčová slova

Následující tabulka uvádí direktivy prekompileru, které jsou podobné v X++ a C#.

Keyword X++ jazyk C# Comments
#define V X++ je možné definovat název předkompilerované proměnné a této proměnné lze dát hodnotu. V jazyce C# je možné definovat název proměnné prekompileru, ale pro tuto proměnnou nelze zadat žádnou hodnotu. Všechny #define v jazyce C# musí také nastat v horní části souboru a nesmí nastat po žádném kódu, jako je příkaz using nebo deklarace třídy. Kompilátor jazyka C# může zadat parametr příkazového /define řádku pro definování názvu proměnné předkompileru bez definování proměnné v libovolném souboru kódu jazyka C#. Kompilátor X++ nemá žádný protějšek /define.
#if V X++ může #if určit, zda existuje proměnná prekompileru a zda má proměnná danou hodnotu. V jazyce C# může #if určit pouze to, jestli existuje proměnná prekompileru. Nemůže testovat žádnou hodnotu, protože nelze přiřadit žádnou hodnotu.
#endif V X++ #endif označí konec bloku #if. Ukončí také blok #ifnot. V jazyce C# #endif označí konec bloku #if bez ohledu na to, jestli blok obsahuje #else.

Různá klíčová slova se stejným výsledkem zpracování

Následující tabulka uvádí direktivy prekompileru, které jsou v X++ a C# pojmenované jinak, ale při zpracování poskytují stejné výsledky.

X++ jazyk C# Comments
#ifnot #if #else V X++ není direktiva #else, ale #ifnot poskytuje podobné funkce. V X++ může #ifnot určit, jestli existuje proměnná prekompileru a jestli proměnná nemá konkrétní danou hodnotu. V jazyce C# může #if určit, jestli existuje proměnná prekompileru, když je proměnná '!'. symbol je předponou názvu proměnné.
//BP Deviation documented upozornění #pragma Tyto položky X++ a C# nejsou ekvivalentní, ale existuje částečná podobnost. Oba potlačí zprávy upozornění kompilátoru.
#macrolib . Soubor HPP v jazyce C++ Existuje částečná podobnost mezi direktivou X++ #macrolib a . Soubor HPP v jazyce C++. Obojí může obsahovat několik příkazů #define.

Direktivy prekompileru s výhradním použitím X++

Následující tabulka uvádí direktivy prekompileru X++, které nemají v jazyce C# přímý protějšek.

X++ Comments
#linenumber Direktiva #linenumber slouží k získání čísla řádku, takže může být výstupem do infologu.
Direktiva jazyka C# #line se liší, protože jejím účelem je nastavení čísla řádku.
#defdec #definc
#globaldefine V X++ existuje malý rozdíl mezi #globaldefine a #define. Rozdíl je v tom, že #globaldefine nikdy nepřepíše aktuální nenulovou hodnotu, která byla přiřazena proměnné prekompileru #define.
Jazyk C# nemá nic podobného tomuto rozdílu, protože v jazyce C# nemůže být název proměnné prekompileru uveden jako hodnota.
#localmacro #macro V X++ #localmacro umožňuje přiřadit víceřádkovou hodnotu proměnné prekompileru. #macro je synonymem, ale #localmacro se doporučuje.
V jazyce C# má direktiva #define část této funkce, ale nemůže přiřadit hodnotu proměnné prekompileru.
#globalmacro V X++ je #globalmacro téměř stejná jako upřednostňovaná #localmacro.

Porovnání: Objektově orientované programování

Objektově orientované programování (OOP) X++ se liší od jazyka C#.

Koncepční porovnání

Následující tabulka porovnává implementaci principů OOP mezi X++ a C#.

Vlastnost X++ jazyk C# Comments
Obsazení Jazyk X++ má klíčová slova ajako, které slouží k bezpečnému a explicitnímu downcastu. Tip: X++ nevyžaduje použití klíčového slova jako při downcastu proměnné základní třídy na odvozenou proměnnou třídy. Doporučujeme ale, aby všechny příkazy downcast používaly jako klíčové slovo. Objekt lze přetypovat nahoru nebo dolů cestu dědičnosti. Downcasty vyžadují klíčové slovo. Další informace o klíčových slovech X++ najdetev tématu Operátory výrazů: Is a As for Dědičnost.
Lokální funkce Metoda může obsahovat deklaraci a tělo kódu pro nula nebo více místních funkcí. Pouze tato metoda může mít volání místní funkce. C# 3.0 podporuje výrazy lambda, které mají určitou podobnost s anonymními funkcemi a místními funkcemi. Výrazy lambda se často používají s delegáty.
Přetížení metody Přetížení metody není podporováno. Název metody může nastat pouze jednou pro každou třídu. Podporuje se přetížení metody. Název metody může probíhat vícekrát v jedné třídě s různými podpisy parametrů v každém případě. X++ podporuje volitelné parametry metod. Volitelné parametry mohou částečně napodobovat přetížení metody. Další informace najdete v řádku pro volitelné parametry v této tabulce.
Přepsání metody Přepsání metody je podporováno. Odvozená třída může mít metodu se stejným názvem jako v základní třídě, pokud je podpis parametru v obou případech stejný. Jedinou výjimkou je, že přepsání metody může přidat výchozí hodnotu parametru. Přepsání metody je podporováno. Virtuální klíčové slovo musí být použito na metodu předtím, než lze metodu přepsat v odvozené třídě. Koncept přepsání metody zahrnuje název metody, jeho podpis parametru a jeho návratový typ. Koncept přepsání metody se nepoužije, pokud se základní metoda a metoda přepsání liší v některém z těchto aspektů.
Volitelné parametry Za deklaraci parametru může následovat výchozí přiřazení hodnoty. Volající metody má možnost předat hodnotu pro tento parametr nebo ignorovat parametr přijmout výchozí hodnotu. Tato funkce napodobuje přetížení metody, protože dvě volání stejného názvu metody mohou předat různá čísla parametrů. Každý parametr, který má výchozí hodnotu, musí následovat za posledním parametrem, který nemá výchozí hodnotu. Klíčové slovo parametru podporuje volitelné parametry. I bez klíčového slova params může přetížení metody z hlediska volajícího poskytovat částečně podobné funkce. Další informace najdete v tématu Parametry a rozsah a použití volitelných parametrů.
Jednoduchá dědičnost Třídu X++ můžete odvodit z jiné třídy X++ pomocí klíčového slova extends v uzlu classDeclaration třídy v AOT. Žádná třída implicitně odvozuje přímo z jiné třídy. Pokud chcete, aby vaše třída byla přímo odvozena od Object třídy, musíte použít klíčové slovo extends . U klíčového slova extends můžete zadat pouze jednu třídu.

Upozornění: Při úpravě základní třídy X++, ze které jsou odvozeny jiné třídy, je nutné znovu zkompilovat tuto základní třídu pomocí kompilátoru forward. Tato možnost zajišťuje, že odvozené třídy jsou také rekompilovány. Chcete-li zajistit, aby odvozené třídy byly také rekompilovány, klepněte pravým tlačítkem myši na uzel základní třídy a potom klepněte na tlačítko Add-Ins Kompilace > vpřed. Alternativou při kliknutí na kompilaci sestavení > (nebo stisknutí klávesy F7) je někdy nedostatečná změna základní třídy.

Třída může implementovat nula na mnoho rozhraní.

Tabulka X++ implicitně dědí z Common tabulky a z xRecord třídy.
Jazyk C# používá klíčové slovo extends k odvození z jiné třídy. Všechny třídy rozhraní .NET Framework implicitně odvozují z System.Object třídy, pokud nejsou explicitně odvozeny z jiné třídy.

Porovnání klíčových slov

Následující tabulka uvádí klíčová slova související s OOP v X++ a C#.

Keyword X++ jazyk C# Comments
abstract Žádný rozdíl.
třída Modifikátory veřejné a soukromé jsou ignorovány u deklarací tříd. Neexistuje koncept seskupení tříd oboru názvů. V názvech tříd nejsou žádné tečky (.). Modifikátory veřejné a soukromé lze použít k úpravě deklarací třídy. Jazyk C# má také interní klíčové slovo, které souvisí s tím, jak se třídy seskupují do souborů sestavení. Neexistuje koncept chráněné třídy, pouze chráněných členů třídy.
rozšiřuje Deklarace třídy může dědit z jiné třídy pomocí klíčového slova extends . Dvojtečka (:) se používá v X++, kde se klíčová slova rozšiřují a implementují .
závěrečný Konečnou metodu nelze přepsat v odvozené třídě. Konečnou třídu nelze rozšířit. Klíčové slovo zapečetěné ve třídě znamená totéž, co konečné znamená ve třídě X++.
implementuje Deklarace třídy může implementovat rozhraní pomocí implements klíčového slova.
interface Rozhraní může určit metody, které třída musí implementovat. Rozhraní může určit metody, které třída musí implementovat.
new Nové klíčové slovo slouží k přidělení nové instance třídy. Pak se konstruktor automaticky zavolá. Každá třída má přesně jeden konstruktor a konstruktor je pojmenován new. Můžete se rozhodnout, jaké parametry má konstruktor zadat. Nové klíčové slovo slouží k vytvoření nové instance třídy. Pak se konstruktor automaticky zavolá. Samotné metody konstruktoru nemají název new, mají stejný název jako třída.

Poznámka:Nové klíčové slovo lze také použít pro metodu, ke změně způsobu, jakým metoda přepisuje stejnou metodu v základní třídě.

X++ i C# předpokládají výchozí konstruktor pro třídy, které nemají žádný konstruktor explicitně napsaný v kódu.
nula Žádný rozdíl.
soukromé a chráněné Soukromá a chráněná klíčová slova lze použít k úpravě deklarace člena třídy. Soukromá a chráněná klíčová slova lze použít k úpravě deklarace člena třídy.
public Metoda, která není upravena pomocí veřejné, chráněné nebo soukromé , má výchozí úroveň přístupu veřejné. Metoda, která není upravena pomocí veřejného, chráněného nebo privátního , má výchozí úroveň přístupu privátní.
statické Metoda může být statická, ale pole nemůže. Metody i pole můžou být statické.
super Super klíčové slovo se používá v odvozené třídě pro přístup ke stejné metodě ve své základní třídě. void method2()
{
// Call method2 method
// on the base class.
super();
}
Základní klíčové slovo se používá v odvozené třídě pro přístup k různým metodám v její základní třídě.
void method2()
{
// Call methods on
// the base class.
base.method2();
base.method3();
}
V jazyce C# existuje speciální syntaxe pro použití základu pro volání základního konstruktoru.
toto Pro volání z jedné metody instance do jiné na stejném objektu je vyžadován kvalifikátor pro volanou metodu. Klíčové slovo , které je k dispozici jako kvalifikátor pro aktuální objekt. Pro volání z jedné instance metody do jiné na stejném objektu není vyžadován kvalifikátor pro volanou metodu. Toto klíčové slovo je však k dispozici jako kvalifikátor pro aktuální objekt. V praxi může být klíčové slovo užitečné zobrazením informací IntelliSense.
finalize Třída Object obsahuje metodu finalize . Metoda finalize není konečná a lze ji přepsat. Zdá finalize se, že metoda se podobá System.Object.Finalize metodě v jazyce C#, ale v X++ finalize metoda nemá žádný zvláštní význam. Objekt se automaticky odebere z paměti, když poslední odkaz na objekt přestane odkazovat na objekt. K tomu může dojít například v případě, že poslední odkaz zmizí z rozsahu nebo je přiřazen k odkazu jiný objekt. Finalize Metody a Dispose jsou běžné u některých typů tříd. Systém uvolňování paměti volá Finalize a Dispose metody při zničení a objektu. V jazyce C# System.GC.Collect lze volat metodu v rozhraní .NET Framework pro spuštění uvolňování paměti. V X++ není podobná funkce, protože X++ používá deterministický systém uvolňování paměti.
main Třídy, které jsou vyvolány z nabídky, mají svou main metodu volané systémem. Třídy, které jsou vyvolány z konzoly příkazového řádku, mají svou Main metodu volanou systémem.

Porovnání: Třídy

Při použití jazyka C# v rozhraní .NET Framework se třídy seskupí do oborů názvů. Každý obor názvů se zaměřuje na funkční oblast, jako jsou operace se soubory nebo reflexe. Pokud však používáte třídy v X++, neexistují žádné viditelné seskupení, jako je obor názvů.

Porovnání: Třídy o reflexi

V X++ TreeNode třída poskytuje přístup ke stromu objektu aplikace (AOT). Třída TreeNode je středem funkce reflexe v X++. Třídu TreeNode a její metody lze porovnat s oborem System.Reflection názvů v rozhraní .NET Framework, který jazyk C# používá.

Následující tabulka uvádí několik tříd, které jsou k dispozici při psaní kódu jazyka C#. Jedná se o třídy rozhraní .NET Framework. Pro tuto tabulku jsou všechny třídy jazyka System.Reflection C# v oboru názvů, pokud nejsou zadány jinak. Každý řádek zobrazuje odpovídající třídu nebo člen třídy, který je pro vás k dispozici při psaní kódu X++.

X++ jazyk C# Comments
TreeNode System .Assembly Sestavení je první třída, která se má použít, když program jazyka C# musí shromáždit informace o reflexi. Statické metody třídy X++ TreeNode jsou výchozím bodem reflexe v X++.
TreeNode System .Type Metody instance odpovídající metodám TreeNode instance v .System.Type
TreeNode .AOTgetSource MethodInfo Metoda AOTgetSource vrátí několik informací dohromady v jednom řetězci. To zahrnuje zdrojový kód X++ v metodě. Naproti tomu MethodInfo má samostatný člen pro každou část informací.
TreeNode .AOTfirstChild TreeNode .AOTnextSibling TreeNode .AOTiterator AOTiterator MethodInfo[] (pole) V jazyce C# GetMethods vrátí metoda pro System.Type vrací pole MethodInfo objektů. Pole můžete procházet běžnou technikou zvýšení indexeru. Naproti tomu model X++ slouží k navigaci ve stromovém ovládacím prvku AOT. Metody TreeNodeAOTfirstChild navigace a AOTnextSibling jejich provádění. Jako ekvivalentní alternativu je třída X++ AOTiterator navržena pro navigaci ve stromu řízení AOT. Uzel třídy je nadřazený nad několika uzly metody. Kroky AOTiterator pro podřízené uzly vracející jednotlivé uzly jako jinou TreeNode instanci. Další prostředky metody TreeNode , které jsou pojmenovány AOTparent a AOTprevious.
TreeNode .AOTgetProperty TreeNode .AOTgetProperties TreeNode .AOTname PropertyInfo V X++ AOTgetProperties metoda vrátí dlouhý řetězec, který obsahuje páry name-value pro všechny vlastnosti objektu TreeNode. Metoda AOTname vrátí řetězec, který obsahuje pouze hodnotu vlastnosti name.
TreeNode .AOTsave TreeNode .AOTinsert System .Reflection .Emit (obor názvů tříd) Metoda AOTsave použije změny z objektu TreeNode v kódu X++ do AOT a změny se zachovají. Ukázku velkého kódu naleznete v tématu TreeNode.AOTsave – metoda.

Porovnání: Třídy o vstupně-výstupních operacích souborů

Existuje několik tříd, které provádějí vstup a výstup souborů (V/V). V rozhraní .NET Framework, který se používá v jazyce C#, se protějšky těchto tříd nacházejí v System.IO oboru názvů.

Následující tabulka uvádí několik tříd rozhraní .NET Framework pro jazyk C#, které jsou v System.IO oboru názvů. Každý řádek v tabulce zobrazuje třídu nebo metodu X++, která nejlépe odpovídá třídě rozhraní .NET Framework.

X++ jazyk C# Comments
BinaryIo FileStream BinaryReader BinaryWriter Třídy X++, jako BinaryIo jsou například rozšiřující z abstraktní třídy Io , slouží jako datový proud a slouží také jako čtenář a zapisovač pro tento stream. V jazyce C# je stream samostatnou třídou od třídy, která má konkrétnější metody čtení a zápisu.
TextBuffer MemoryStream Tyto třídy obsahují vyrovnávací paměť v paměti a některé metody považují vyrovnávací paměť za soubor na pevném disku.
WINAPI::createDirectory WINAPI::folderExists WINAPI::removeDirectory Directory DirectoryInfo Path X++ může použít statické metody ve WINAPI třídě pro mnoho základních funkcí operačního systému, které zahrnují adresáře.
WINAPI::getDriveType DriveInfo DriveType Tyto třídy a metody slouží k získání informací souvisejících s jednotkami.
WINAPI::copyFile WINAPI::createFile WINAPI::d eleteFile WINAPI::fileExists File FileAttributes FileInfo X++ může použít statické metody ve WINAPI třídě pro mnoho základních funkcí operačního systému, které zahrnují soubory.
CommaIo Comma7Io (Žádná odpovídající třída.) Tyto třídy X++ mohou generovat soubory, které může aplikace Microsoft Excel importovat. V X++ je odkaz na knihovnu EPPlus k dispozici pro další interakci s Excelem.
AsciiIo TextIo FileStream TextReader TextWriter Tyto třídy používají různé znakové stránky.
Io Stream StreamReader StreamWriter FileStream Často se používají jako základní třídy, které rozšiřují jiné třídy.
CodeAccessPermission FileIoPermission System.Security .CodeAccessPermission Obor názvů System.Security.Permissions zahrnuje následující třídy:
  • CodeAccessSecurityAttribute
  • FileIOPermissionAttribute
  • FileIOPermission
  • FileIOPermissionAccess
Koncepty a metody assert, demanda revertAssert platí pro oba jazyky. V deny jazyce X++ ale nejsou dostupné metody a revertDeny metody, které jsou dostupné v jazyce C#.

Porovnání X++, ANSI SQL: VÝBĚR SQL

V X++ se syntaxe příkazu SQL select liší od specifikace ANSI (American National Standards Institute).

Výběr jedné tabulky

Následující tabulka uvádí rozdíly mezi příkazy select jazyka X++ SQL a ANSI SQL.

Vlastnost X++ SQL ANSI SQL Comments
Název tabulky v klauzuli from Klauzule From uvádí instanci vyrovnávací paměti záznamu deklarovanou z tabulky, například z CustTable tabulky. Klauzule From obsahuje název tabulky, nikoli název vyrovnávací paměti. Vyrovnávací paměť záznamu má všechny metody, které xRecordtřída má v X++.
Syntaxe pořadí podle klauzule where . Klauzule order by musí být uvedena před klauzulí where . Klauzule order by se musí objevit za klauzulí from nebo join . Klauzule group by musí dodržovat stejná pravidla umístění syntaxe jako pořadí podle následujícího pořadí. Klauzule order by musí být uvedena za klauzulí where . Klauzule where se musí objevit za klauzulí from nebo join . V jazyce X++ i ANSI SQL se klauzule from a join musí objevit před klauzulí order by a where .
Negace podmínek. Vykřičník (!) se používá pro negaci. Pro negaci se používá klíčové slovo. X++ nepodporuje syntaxi !like. Místo toho musíte použít ! klauzule.
Zástupné znaky pro operátor like . 0 až n – hvězdička (*)
Přesně 1 – otazník ('?')
0 až mnoho – znaménko procent ("%')
Přesně 1 – podbar ('_')
Logické operátory v klauzuli where . A - &
Nebo – ||
A – a
Nebo – nebo

Příklad kódu

Následující příklad kódu znázorňuje funkce v předchozí tabulce.

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
***/

Klíčová slova jazyka SQL jazyka X++

Mezi klíčová slova X++ SQL patří klíčová slova, která nejsou součástí ANSI SQL:

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

Join – klauzule

Následující tabulka uvádí rozdíly mezi klíčovým slovem spojení jazyka X++ SQL a ANSI SQL.

Vlastnost X++ SQL ANSI SQL Comments
Seznam sloupců Sloupce v seznamu sloupců musí pocházet z tabulky uvedené v klauzuli from , a ne z žádné tabulky v klauzuli join . Sloupce v seznamu nemůžou být kvalifikované podle názvu tabulky. Sloupce v seznamu sloupců můžou pocházet z libovolné tabulky v klauzulích from nebo join . Pomáhá ostatním udržovat váš kód, když opravíte sloupce v seznamu s jejich názvem tabulky. Další informace naleznete v tématu Select Statements on Fields.
Syntaxe klauzule join Klauzule join se řídí klauzulí where . Klauzule join se řídí tabulkou v klauzuli from . V příkladu kódu X++ je kritérium spojení rovnost SalesPoolId hodnot.
Vnitřní klíčové slovo. Výchozí režim spojení je vnitřní spojení. Neexistuje vnitřní klíčové slovo. Výchozí režim spojení je vnitřní spojení. Vnitřní klíčové slovo je k dispozici, aby byl kód explicitní. Vnější klíčové slovo existuje v X++ SQL i ANSI SQL.
Klíčová slova zleva a doprava Klíčová slova vlevo a vpravo nejsou k dispozici. Všechna spojení jsou ponechána. Klíčová slova vlevo a vpravo jsou k dispozici pro úpravu klíčového slova spojení . Žádné komentáře.
Operátor rovnosti. Operátor dvojitého rovnítku ('==) slouží k otestování rovnosti dvou hodnot. Operátor jednotného rovnítku ('=) slouží k otestování rovnosti dvou hodnot. Žádné komentáře.

Příklad kódu

Následující příklad kódu znázorňuje syntaxi spojení v 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);
    }
}

Agregovaná pole

Následující tabulka uvádí některé rozdíly v tom, jak jsou agregovaná pole v seznamu vybraných sloupců odkazována mezi X++ SQL a ANSI SQL. Agregační pole jsou ta, která jsou odvozena funkcemi, jako je součet nebo průměr.

Vlastnost X++ SQL ANSI SQL Comments
Alias názvu agregace pole Agregační hodnota je v poli, které se agregovalo. Pomocí klíčového slova můžete označit agregované pole aliasem názvu. Na alias se dá odkazovat v následujícím kódu. Další informace najdete v tématu Agregační funkce: Rozdíly mezi X++ a SQL

Příklad kódu

V následujícím příkladu kódu znázorňuje volání metody informací způsob, jak odkazovat na agregovaná pole (viz 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.
***/

Další rozdíly

Následující tabulka uvádí další rozdíly příkazu select mezi X++ SQL a ANSI SQL.

Vlastnost X++ SQL ANSI SQL Comments
Klíčové slovo s klíčovým slovem Neexistuje klíčové slovo . Klíčové slovo s klíčovým slovem umožňuje zadat kritéria filtru pro řádky, které jsou generovány klauzulí group by. Žádné komentáře.
Výsledky null. Pokud klauzule where filtruje všechny řádky, v době výběru příkazu select se do sestavy nevrátí žádný zvláštní počet řádků. Pokud klauzule where vyfiltruje všechny řádky, vrátí se zvláštní počet řádků. Hodnota počtu je 0. Žádné komentáře.
Kurzory pro navigaci ve vrácených řádcích Příkaz while select poskytuje funkce kurzoru. Alternativou je použití dalšího klíčového slova. Můžete deklarovat kurzor pro smyčku přes řádky, které jsou vráceny z příkazu select .
Klauzule From Klíčové slovo from je volitelné, pokud nejsou uvedeny žádné sloupce a odkazuje se pouze na jednu tabulku. Následující dvě možnosti syntaxe jsou ekvivalentní:
select \* from tCustTable;
select tCustTable;
Příkaz select nemůže číst z tabulky, pokud se nepoužije klauzule from . V X++ SQL jednoduchý příkaz select vyplní proměnnou vyrovnávací paměti tabulky prvním řádkem, který byl vrácen. To je ilustrováno následujícím fragmentem kódu:
select \* from tCustTable;
info(tCustTable.Name);