X++ operators

In dit artikel worden de operators beschreven die worden ondersteund in X++.

Assignment operators

Een toewijzingsoperator verandert de waarde van een variabele of veld. In de volgende tabel ziet u de X++-toewijzingsoperatoren. Er is geen verschil tussen operatoren met een voorvoegsel en een voorvoegsel.

Operator Description
= Wijs de expressie rechts van het gelijkteken toe aan de variabele links.
+= Wijs de huidige variabelewaarde plus de expressie aan de rechterkant toe aan de variabele aan de linkerkant.
++ Verhoog de variabele met 1.
-= Wijs de huidige variabelewaarde minus de expressie aan de rechterkant toe aan de variabele aan de linkerkant.
-- Verlaag de variabele met 1.

Codevoorbeelden voor toewijzingsoperatoren

// An example of assignment operators and their output. 
static void Example1()
{
    int i = 1;
    // Using the = operator. i is assigned the value of i, plus 1. i = 2.
    i = i + 1;
    info(strFmt("Example 1: The result is "), i); // The result is 2.
}

static void Example2()
{
    int i = 1;
    // Using the += operator. i is assigned the value of i, plus 1. 
    // i = 2 (i = i + 1).
    i += 1;
    info(strFmt("Example 2: The result is "), i); // The result is 2. 
}

static void Example3()
{
    int i = 1;
    // Using the ++ operator. i is incremented by 1, and then 
    // by 1 again in the second statement. The final value of i is 3.
    i++;
    ++i;
    info(strFmt("Example 3: The result is "), i); // The result is 3. 
}

static void Example4()
{
    int i = 1;
    // Using the -= operator. i is assigned the value of i minus 1. 
    // i = 0 (i = i - 1).
    i -= 1;
    info(strFmt("Example 4: The result is "), i); // The result is 0. 
}

static void Example5()
{
    int i = 1;
    // Using the -- operator. i is decremented by 1, and then by 
    // 1 again in the second statement. The final value of i is -1.
    i--;
    --i;
    info(strFmt("Example 5: The result is "), i); // The result is -1. 
}

Arithmetic operators

Gebruik rekenkundige operatoren om numerieke berekeningen uit te voeren. De meeste operatoren zijn binair en nemen twee operanden. De operator not (~) is echter unair en heeft slechts één opeend nodig. Syntaxis voor binaire operatoren: expression1ArithmeticOperatorexpression2 Syntaxis voor unaire operatoren: ArithmeticOperatorexpression1

Operator Description
<< De operator in de linkerploeg voert expressie2 linkerverschuiving (vermenigvuldiging met 2) uit op expressie1.
>> De rechter ploegoperator voert expressie2 rechterdienst (delen door 2) uit op expressie1.
* De operator vermenigvuldigenexpressie1 met expressie2.
/ De deeloperator deelt expressie1 door expressie2.
DIV De operator voor de deling van gehele getallen voert een deling van gehele getallen uit van expressie1 door expressie2.
MOD De operator voor de rest van het gehele getal retourneert de rest van een gehele deling van expressie1 door expressie2.
~ De operator niet , of unaire operator, voert een binaire not-bewerking uit.
& De binaire AND-operator voert een binaire AND-bewerking uit op expressie1 en expressie2.
^ De binaire XOR-operator voert een binaire XOR-bewerking uit op expressie1 en expressie2.
| De binaire OR-operator voert een binaire of bewerking uit op expressie1 en expressie2.
+ De plusoperator voegt expressie1 toe aan expressie2.
- De minoperator trekt expressie2 af van expressie1.
? De ternaire operator neemt drie uitdrukkingen aan: expressie1 ? expressie2 : expressie3. Als expressie1 waar is, wordt expressie2 geretourneerd. Anders wordt expressie3 geretourneerd.

Codevoorbeelden voor rekenkundige operatoren

int a = 1 << 4;      // Perform four left shifts on 1 (1*2*2*2*2). a=16.
int b = 16 >> 4;     // Perform four right shifts on 16 (16/2/2/2/2). b=1.
int c = 4 * 5;       // Multiply 4 by 5. c=20.
int d = 20 / 5;      // Divide 20 by 5. d=4.
int e = 100 div 21;  // Return the integer division of 100 by 21. e=4 (4*21 = 84, remainder 16).
int f = 100 mod 21;  // Return the remainder of the integer division of 100 by 21. f=16.
int g = ~1;          // Binary negate 1 (all bits are reversed). g=-2.
int h = 1 & 3;       // Binary AND. Return the bits that are in common in the two integers. h=1.
int i = 1 | 3;       // Binary OR. Return the bits that are set in either 1 or 3. i=3.
int j = 1 ^ 3;       // Binary XOR. Return the bits that are set in 1 and NOT set in 3, and vice versa. j=2.
int k = 1 + 3;       // Add 1 and 3. k=4.
int l = 3 - 1;       // Subtract 1 from 3. l=2.
int m = (400 > 4) ? 1 : 5;  // If 400>4, 1 is returned. Otherwise, 5 is returned. Because 400>4, 1 is returned. m=1.

Expression operators

De as en is expressie-operators besturen sombere opdrachten. Sombere toewijzingen hebben betrekking op klasse- of tabelovererving. Opdrachtverklaringen die impliciet somber zijn, kunnen fouten veroorzaken die moeilijk te voorspellen en te diagnosticeren zijn. Gebruik het as trefwoord om je downcasts expliciet te maken. Gebruik het is trefwoord om te testen of een downcast geldig is tijdens runtime.

Het als trefwoord

Gebruik het as trefwoord voor opdrachten die worden verlaagd van een basisklassevariabele naar een afgeleide klassevariabele. Het as trefwoord vertelt andere programmeurs en de compiler dat je gelooft dat de downcast geldig is tijdens runtime.

  • De compiler rapporteert een fout voor downcast-opdrachtinstructies waarin het as trefwoord ontbreekt.
  • Tijdens runtime zorgt het as trefwoord ervoor dat de downcast-toewijzingsinstructie wordt toegewezen null als de downcast niet geldig is.
  • Gebruik het is trefwoord om veilig te testen of het as trefwoord werkt.

Codevoorbeeld voor het trefwoord als

In het volgende codevoorbeeld breidt de klasse DerivedClass de klasse BaseClass uit. Het codevoorbeeld bevat twee geldige toewijzingen tussen de variabelen basec en derivedc . Voor de upcast-toewijzing aan basec is het as trefwoord niet vereist, maar voor de downcast-toewijzing aan derivedc is het as trefwoord wel vereist. De volgende code compileert en draait zonder fouten.

static void AsKeywordExample()
{
    // DerivedClass extends BaseClass.
    BaseClass basec;
    DerivedClass derivedc;
    // BottomClass extends DerivedClass.
    BottomClass bottomc;
    derivedc = new DerivedClass();
    // AS is not required for an upcast assignment like this.
    basec = derivedc;
    // AS is required for a downcast assignment like this.
    derivedc = basec as DerivedClass;
    bottomc = new BottomClass();
    // AS causes this invalid downcast to assign null.
    bottomc = basec as DerivedClass;
}

Het is trefwoord

Het is trefwoord controleert of een object een subtype is van een opgegeven klasse. De is expressie retourneert true als het object een subtype van de klasse is of als het object hetzelfde type is als de klasse. De compiler rapporteert een fout als een is trefwoordexpressie twee typen vergelijkt, maar geen van beide typen is een subtype van de andere en ze zijn niet van hetzelfde type. De compiler rapporteert een vergelijkbare fout voor elke gewone toewijzingsinstructie tussen twee typen, waarbij geen van beide typen een subtype van de andere is en ze niet van hetzelfde type zijn. Tijdens runtime is het type variabele dat verwijst naar het onderliggende object niet relevant voor het is zoekwoord. Het is trefwoord zorgt ervoor dat het systeem het object verifieert waarnaar de variabele verwijst, niet het gedeclareerde type van de variabele die naar het object verwijst.

Codevoorbeelden voor het trefwoord is

In de volgende codevoorbeelden worden de voorwaarden geïllustreerd die bepalen of een is expressie waar of onwaar retourneert. De codevoorbeelden zijn afhankelijk van het feit dat de klasse Form en de klasse Query beide de klasse TreeNode uitbreiden.

// The compiler issues an error for the following code. 
// The compiler ascertains that the Form class and the Query class are not 
// part of the same inheritance hierarchy. Both the Form class and the Query class
// extend the TreeNode class, but neither Form nor Query is a subtype of the other.
Form myForm = new Form();
info(strFmt("%1", (myForm is Query)));

// The Infolog displays 0 during run time, where 0 means false. No supertype 
// object can be considered to also be of its subtype class.
TreeNode myTreeNode = new TreeNode();
info(strFmt("%1", (myTreeNode is Form)));

// The Infolog displays 0 during run time, where 0 means false. A null 
// reference causes the is expression to return false.
Form myForm;
info(strFmt("%1", (myForm is Form)));

// The Infolog displays 1 during run time, where 1 means true. 
// An object is an instance of its own class type.
Form myForm = new Form();
info(strFmt("%1", (myForm is Form)));

// The Infolog displays 1 during run time, where 1 means true. 
// Every subtype is also of its supertype.
Form myForm = new Form();
info(strFmt("%1", (myForm is TreeNode)));

// The Infolog displays 1 during run time, where 1 means true. 
// The type of the underlying object matters in the is expression,
// not the type of the variable that references the object.
Form myForm = new Form();
TreeNode myTreeNode;
myTreeNode = myForm; // Upcast.
info(strFmt("%1", (myTreeNode is Form)));

Codevoorbeeld voor de is en als trefwoorden

Het volgende codevoorbeeld bevat een typisch gebruik van het is trefwoord. Het as trefwoord wordt gebruikt nadat het is trefwoord heeft gecontroleerd of het as trefwoord slaagt. In dit voorbeeld zijn de is trefwoorden en as hoofdletters om ze beter zichtbaar te maken.

static void IsKeywordExample() 
{
    DerivedClass derivedc;
    BaseClass basec;
    basec = new DerivedClass();  // An upcast.
    if (basec IS DerivedClass)
    {
        info("Test 1: (basec IS DerivedClass) is true. Good.");
        derivedc = basec AS DerivedClass;
    }
    basec = new BaseClass();
    if (!(basec IS DerivedClass))
    {
        info("Test 2: !(basec IS DerivedClass) is true. Good.");
    }
}

//Output to the Infolog
Test 1: (basec IS DerivedClass) is true. Good.
Test 2: (!(basec IS DerivedClass)) is true. Good.

Objectklasse als speciaal geval

De klasse Object kan worden weergegeven als een speciaal geval in de overervingsfunctionaliteit. De compiler omzeilt typecontrole voor toewijzingen van en naar variabelen waarvan wordt beweerd dat ze van het type Object zijn. Sommige klassen erven van de klasse Object , sommige klassen erven van een andere klasse en sommige klassen erven niet van een klasse. Hoewel de klasse Dialog niet wordt overgenomen van een klasse, werken de opdracht- en aanroepinstructies in het volgende codevoorbeeld wel. Als de opdracht echter is bank4 = dlog3;, zal deze mislukken tijdens het compileren, omdat de klassen Bank en Dialog geen overervingsrelatie met elkaar hebben. De compiler voert slechts één kleine validatie uit op toewijzingen aan een variabele waarvan is vastgesteld dat deze van de klasse Object is. De compiler controleert of het item dat wordt toegewezen aan de variabele Object een instantie van een klasse is. De compiler staat niet toe dat een exemplaar van een tabelbuffer wordt toegewezen aan de objectvariabele. Bovendien staat de compiler niet toe dat primitieve gegevenstypen, zoals int of str, worden toegewezen aan de objectvariabele.

static void ObjectExample()
{
    Bank bank4;
    Object obj2;
    Dialog dlog3 = new Dialog("Test 4.");
    obj2 = dlog3;  // The assignment does work.
    obj2.run(false);  // The call causes the dialog to appear.
    info("Test 4a is finished.");
}

Tables

Alle tabellen nemen rechtstreeks deel uit van de tabel Algemeen systeem, tenzij ze expliciet van een andere tabel worden overgeërfd. De gemeenschappelijke tabel kan niet worden geïnstantieerd. Het bestaat niet in de onderliggende fysieke database. De Common table is afkomstig van de xRecord-klasse , maar op een speciale manier die niet geschikt is voor het is trefwoord of het as trefwoord. Wanneer het as trefwoord wordt gebruikt om een ongeldige downcast uit te voeren in tabellen, verwijst de doelvariabele naar een onbruikbare niet-null-entiteit. Elke poging om de doelvariabele te de-refereren zal een fout veroorzaken die het programma stopt.

De is en als trefwoorden en uitgebreide gegevenstypen

Elk uitgebreid gegevenstype heeft de eigenschap Extends. De stijl van overerving die door deze eigenschap wordt beheerd, verschilt van de stijl van overerving waarvoor de is trefwoorden en as zijn ontworpen.

Relational operators

De volgende tabel bevat de relationele operatoren die kunnen worden gebruikt in X++. De meeste operatoren zijn binair en nemen twee operanden. De operator not (!) is echter unair en heeft slechts één opeend nodig. Syntaxis voor binaire operatoren: expression1 relationalOperatorexpression2 Syntaxis voor unaire operatoren: relationalOperatorexpression1

Operator Description
like De like relationele operator retourneert waar als expressie1 gelijk is aan expressie2.
== De gelijke relationele operator retourneert waar als beide uitdrukkingen gelijk zijn.
>= De operator groter dan of gelijk aan de relationele operator retourneert waar als expressie1 groter is dan of gelijk is aan expressie2.
<= De operator kleiner dan of gelijk aan relationele geeft waar terug als expressie1 kleiner is dan of gelijk is aan expressie2.
> De operator groter dan relationeel retourneert waar als expressie1 groter is dan expressie2.
< De operator kleiner dan geeft waar terug als expressie1 kleiner is dan expressie2.
!= De niet-gelijke relationele operator retourneert waar als expressie1 verschilt van (dat wil zeggen, als deze niet gelijk is aan) expressie2.
&& De operator en relationele retourneert waar als zowel expressie1 als expressie2 waar zijn.
|| De relationele operator of retourneert waar als expressie1 of expressie2 waar is, of als beide waar zijn.
! De niet - of unaire relationele operator ontkent de uitdrukking. Het retourneert waar als de uitdrukking onwaar is en onwaar als de uitdrukking waar is.

Dezelfde operator

De like operator kan worden gebruikt * als een jokerteken voor nul of meer tekens en ? als een jokerteken voor één teken. De maximale lengte van het operaland is 1.000 tekens. De like operator wordt geëvalueerd door de onderliggende SQL, dus het resultaat kan verschillen op verschillende installaties. Als de expressies die u vergelijkt een bestandspad bevatten, moet u vier backslashes tussen elk element opnemen, zoals wordt weergegeven in het volgende voorbeeld.

select * from xRefpaths
where xRefPaths.Path like "\\\\Classes\\\\AddressSelectForm"

De gelijke (==) operator

Wanneer u de operator equal (==) gebruikt om objecten te vergelijken, worden de objectverwijzingen vergeleken, niet de objecten zelf. Dit gedrag kan problemen veroorzaken als u twee objecten vergelijkt, waarvan het ene zich op de server bevindt en het andere op de client. In deze gevallen moet u de gelijke methode gebruiken in de klasse Object . U kunt deze methode overschrijven om op te geven wat het betekent dat twee objecten gelijk zijn. Als u de methode voor gelijk niet overschrijft, is de vergelijking identiek aan de vergelijking die wordt uitgevoerd door de operator gelijk (==).

Codevoorbeelden voor relationele operatoren

"Jones" like "Jo?es"  // Returns true, because the ? is equal to any single character.
"Fabrikam, Inc." like "Fa*"  // Returns true, because the * is equal to zero or more characters.
(( 42 * 2) == 84)  // Returns true, because 42*2 is equal to 84.
today() >= 1\1\1980  // Returns true, because today is later than January 1, 1980.
((11 div 10) >= 1)  // Returns true, because 11 div 10 is 1 (therefore, >= 1 is true).
(11<= 12)  // Returns true, because 11 is less than 12.
((11 div 10) > 1)  // Returns false, because 11 div 10 is 1.
(11 div 10) < 1)  // Returns false, because 11 div 10 is 1.
(11 != 12)  // Returns true, because 11 is not equal to 12.
(1 == 1) && (3 > 1)  // Returns true, because both expressions are true.

Operator precedence

De volgorde waarin een samengestelde expressie wordt geëvalueerd kan belangrijk zijn. Geeft (x + y / 100) bijvoorbeeld een ander resultaat, afhankelijk van of de optelling of de deling eerst wordt gedaan. U kunt haakjes (()) gebruiken om de compiler expliciet te vertellen hoe een expressie moet worden beoordeeld. U kunt bijvoorbeeld opgeven (x + y) / 100. Als u de compiler niet expliciet vertelt in welke volgorde u bewerkingen wilt uitvoeren, wordt de volgorde gebaseerd op de prioriteit die aan de operators is toegewezen. De deeloperator heeft bijvoorbeeld een hogere voorrang dan de opteloperator. Daarom evalueert x + y / 100 de compiler voor de expressie y / 100eerst. Met andere woorden, x + y / 100 is gelijk aan x + (y / 100). Wees expliciet om uw code gemakkelijk leesbaar en te onderhouden te maken. Gebruik haakjes om aan te geven welke operators als eerste moeten worden geëvalueerd. De volgende tabel geeft een overzicht van de operatoren in volgorde van prioriteit. Hoe hoger een operator in de tabel voorkomt, hoe hoger de prioriteit. Operators met een hogere prioriteit worden beoordeeld vóór operators met een lagere prioriteit. Merk op dat de prioriteit van de operator van X++ niet hetzelfde is als de prioriteit van de operator van andere talen, zoals C# en Java.

Groepen marktdeelnemers, in volgorde van prioriteit Operators
Unary - ~ !
Multiplicatief, shift, bitsgewijs EN, bitsgewijs exclusief OR * / % DIV << >> & ^
Additief, bitsgewijs inclusief OR + - |
Relational, equality < <= == != > >= like as is
Logisch (EN,OF) && ||
Conditional ? :

Exploitanten op dezelfde lijn hebben dezelfde voorrang. Als een expressie meer dan één van deze operatoren bevat, wordt deze van links naar rechts geëvalueerd, tenzij toewijzingsoperatoren worden gebruikt. (Toewijzingsoperators worden van rechts naar links beoordeeld.) (logisch&&) en AND (logisch) ||ORhebben bijvoorbeeld dezelfde voorrang en worden van links naar rechts beoordeeld. Therefore:

  • 0 && 0 || 1 is gelijk aan 1
  • 1 || 0 && 0 is gelijk aan 0.