Opérateurs X++

Note

Les groupes d’intérêt communautaire sont maintenant passés de Yammer à Microsoft Viva Engage. Pour rejoindre une communauté Viva Engage et participer aux dernières discussions, remplissez le formulaire Demande d’accès à la Communauté Viva Engage Finances et Opérations et choisissez la communauté que vous souhaitez rejoindre.

Cet article décrit les opérateurs pris en charge dans X++.

Opérateurs d’attribution

Un opérateur d’affectation modifie la valeur d’une variable ou d’un champ. Le tableau suivant montre les opérateurs d’affectation X++. Il n’y a pas de différence entre les opérateurs de préfixe et de postfixe.

Opérateur Description
= Assignez l’expression à droite du signe égal à la variable de gauche.
+= Attribuez la valeur de la variable courante plus l’expression de droite à la variable de gauche.
++ Incrémentez la variable de 1.
-= Attribuez la valeur de la variable courante moins l’expression de droite à la variable de gauche.
-- Diminuez la variable de 1.

Exemples de code pour les opérateurs d’affectation

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

Opérateurs arithmétiques

Utilisez des opérateurs arithmétiques pour effectuer des calculs numériques. La plupart des opérateurs sont binaires et prennent deux opérandes. Cependant, l’opérateur not (~) est unaire et ne prend qu’un seul opérande. Syntaxe pour opérateurs binaires : expression1ExpressionOpérateurArithmétique2 Syntaxe pour opérateursUnaires : expressionOpérateurArithmétique1

Opérateur Description
<< L’opérateur décalage à gauche effectue un décalage à gauche de l’expression2 (multiplication par 2) sur l’expression1.
>> L’opérateur de décalage à droite effectue un décalage à droite de l’expression2 (division par 2) sur l’expression1.
* L’opérateur de multiplication multiplie l’expression1 par l’expression2.
/ L’opérateur divisel’expression1 par l’expression2.
DIV L’opérateur de division entière effectue une division entière de l’expression1 par l’expression2.
MOD L’opérateur de reste entier retourne le reste d’une division entière de l’expression1 par l’expression2.
~ L’opérateur non , ou opérateur unaire, effectue une opération binaire non.
& L’opérateur binaire AND effectue une opération binaire et sur les expressions 1 et expression2.
^ L’opérateur XOR binaire effectue une opération XOR binaire sur les expressions 1 et expression2.
| L’opérateur binaire OR effectue une opération binaire ou sur les expressions 1 et expression2.
+ L’opérateur plus ajoute l’expression1 à l’expression2.
- L’opérateur moins soustrait l’expression2 de l’expression 1.
? L’opérateur ternaire prend trois expressions : expression1 ? expression2 : expression3. Si l’expression1 est vraie, l’expression2 est retournée. Sinon, l’expression3 est retournée.

Exemples de code pour les opérateurs arithmétiques

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.

Opérateurs d’expression

Les as opérateurs d’expression et is contrôlent les affectations de downcast. Les assignations downcast impliquent l’héritage de classe ou de table. Des déclarations d’affectation implicitement dégradées peuvent causer des erreurs difficiles à prévoir et à diagnostiquer. Utilisez ce as mot-clé pour rendre explicites vos déceptions. Utilisez le is mot-clé pour vérifier si un downcast est valide à l’exécution.

Le mot-clé as

Utilisez le as mot-clé pour les affectations qui descendent d’une variable de classe de base vers une variable de classe dérivée. Le as mot-clé indique aux autres programmeurs et au compilateur que vous croyez que le downcast est valide pendant l’exécution.

  • Le compilateur signale une erreur pour les instructions d’assignation en baisse qui n’ont pas le as mot-clé.
  • Au moment de l’exécution, le as mot-clé fait en sorte que l’instruction d’attribution de downcast s’assigne null si la downcast n’est pas valide.
  • Utilisez le is mot-clé pour tester en toute sécurité si le as mot-clé fonctionne.

Exemple de code pour le mot-clé as

Dans l’exemple de code suivant, la classe DerivedClass étend la classe BaseClass . L’exemple de code contient deux affectations valides entre ses variables basec et derivedc . L’attribution upcast à basec ne nécessite pas le as mot-clé, mais l’attribution downcast à derivedc nécessite le as mot-clé. Le code suivant se compile et s’exécute sans erreurs.

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

Le mot-clé is

Le is mot-clé vérifie si un objet est un sous-type d’une classe spécifiée. L’expression is retourne vrai si l’objet est un sous-type de la classe, ou si l’objet est du même type que la classe. Le compilateur signale une erreur si une is expression de mot-clé compare deux types, mais qu’aucun type n’est un sous-type de l’autre, et qu’ils ne sont pas du même type. Le compilateur rapporte une erreur similaire pour toute instruction d’assignation simple entre deux types, où aucun type n’est un sous-type de l’autre, et ils ne sont pas du même type. À l’exécution, le type de variable qui fait référence à l’objet sous-jacent est sans importance pour le is mot-clé. Le is mot-clé amène le système à vérifier l’objet auquel la variable fait référence, et non le type déclaré de la variable qui fait référence à l’objet.

Exemples de code pour le mot-clé is

Les exemples de code suivants illustrent les conditions qui déterminent si une is expression retourne vrai ou faux. Les exemples de code dépendent du fait que la classe Form et la classe Query étendent toutes deux la classe TreeNode .

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

Exemple de code pour les mots-clés is et as

L’exemple de code suivant contient une utilisation typique du is mot-clé. Le as mot-clé est utilisé après que le is mot-clé a vérifié qu’il as réussit. Dans cet exemple, les is mots-clés et as sont en majuscules pour les rendre plus visibles.

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.

Classe d’objet comme cas particulier

La classe Objet peut apparaître comme un cas particulier dans la fonctionnalité d’héritage. Le compilateur contourne la vérification de type pour les affectations vers et depuis des variables déclarées de type Objet. Certaines classes héritent de la classe Objet , d’autres d’une autre classe, et certaines classes n’héritent d’aucune classe. Bien que la classe Dialog ne hérite d’aucune classe, les instructions d’assignation et d’appel dans l’exemple de code suivant fonctionnent. Cependant, si l’affectation est bank4 = dlog3;, elle échouera au moment de la compilation, car les classes Banque et dialogue n’ont aucune relation d’héritage entre elles. Le compilateur effectue une seule petite validation sur les affectations à une variable déclarée appartenant à la classe Objet . Le compilateur vérifie que l’élément assigné à la variable objet est une instance d’une classe. Le compilateur ne permet pas d’attribuer une instance d’un tampon de table à la variable Objet . De plus, le compilateur n’autorise pas l’attribution de types de données primitifs, tels que int ou str, à la variable Objet .

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

Tableaux

Toutes les tables héritent directement de la table système commune, sauf si elles héritent explicitement d’une table différente. La table commune ne peut pas être instanciée. Il n’existe pas dans la base de données physique sous-jacente. La table Common hérite de la classe xRecord , mais d’une manière spéciale qui n’est pas appropriée pour le is mot-clé ou as le mot-clé. Lorsque le as mot-clé est utilisé pour effectuer un downcast invalide parmi les tables, la variable cible fait référence à une entité non nulle inutilisable. Toute tentative de déréférencer la variable cible provoquera une erreur qui arrêtera le programme.

Le is et comme mots-clés et types de données étendues

Chaque type de données étendu possède une propriété Extends . Le style d’héritage que cette propriété contrôle diffère du style d’héritage pour lequel les is mots-clés et as sont conçus.

Opérateurs relationnels

Le tableau suivant liste les opérateurs relationnels pouvant être utilisés dans X++. La plupart des opérateurs sont binaires et prennent deux opérandes. Cependant, l’opérateur not (!) est unaire et ne prend qu’un seul opérande. Syntaxe pour opérateurs binaires : expression1relationalExpression2 Syntaxe pour opérateurs unaires : relationalExpression1

Opérateur Description
like L’opérateur relationnel similaire renvoie vrai si l’expression1 est l’expression2 similaire.
== L’opérateur relationnel égal retourne vrai si les deux expressions sont égales.
>= L’opérateur supérieur ou égal à relationnel renvoie vrai si l’expression1 est supérieure ou égale à l’expression2.
<= L’opérateur inférieur ou égal à relationnel renvoie vrai si l’expression1 est inférieure ou égale à l’expression2.
> L’opérateur supérieur à relationnel renvoie vrai si l’expression1 est supérieure à l’expression2.
< L’opérateur moins que relationnel renvoie vrai si l’expression1 est inférieure à l’expression2.
!= L’opérateur relationnel non égal renvoie vrai si expression1 diffère (c’est-à-dire si elle n’est pas égale à) expression2.
&& L’opérateur relationnel et retourne vrai si les expressions 1 et expression2 sont toutes deux vraies.
|| L’opérateur relationnel ou retourne vrai si expression1 ou expression2 est vraie, ou si les deux sont vraies.
! L’opérateur relationnel non ou unaire nie l’expression. Elle retourne vrai si l’expression est fausse et fausse si l’expression est vraie.

L’opérateur de semblable

L’opérateur like peut l’utiliser * comme caractère joker pour zéro caractère ou plus, et ? comme caractère joker pour un caractère. La longueur maximale de l’opérande est de 1 000 caractères. L’opérateur like est évalué par le SQL sous-jacent, donc le résultat peut différer selon les installations. Si les expressions que vous comparez contiennent un chemin de fichier, vous devez inclure quatre barres obliques entre chaque élément, comme montré dans l’exemple suivant.

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

L’opérateur égal (==)

Lorsque vous utilisez l’opérateur égal (==) pour comparer les objets, ce sont les références aux objets, pas les objets eux-mêmes. Ce comportement pourrait causer des problèmes si vous comparez deux objets, dont l’un est situé sur le serveur et l’autre sur le client. Dans ces cas, vous devriez utiliser la méthode égale dans la classe Objet . Vous pouvez contourner cette méthode pour spécifier ce que signifie que deux objets soient égaux. Si vous ne remplacez pas la méthode égale , la comparaison est identique à celle faite par l’opérateur égal (==).

Exemples de code pour les opérateurs relationnels

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

Préséance opérateur

L’ordre dans lequel l’expression d’un composé est évaluée peut être important. Par exemple, (x + y / 100) donne un résultat différent, selon que l’addition ou la division est faite en premier. Vous pouvez utiliser des parenthèses (()) pour indiquer explicitement au compilateur comment il doit évaluer une expression. Par exemple, vous pouvez spécifier (x + y) / 100. Si vous ne précisez pas explicitement au compilateur l’ordre dans lequel vous voulez que les opérations soient effectuées, cet ordre est basé sur la priorité assignée aux opérateurs. Par exemple, l’opérateur de division a une priorité supérieure à l’opérateur d’addition. Par conséquent, pour l’expression x + y / 100, le compilateur évalue y / 100 en premier. En d’autres termes, x + y / 100 est équivalent à x + (y / 100). Pour rendre votre code facile à lire et à maintenir, soyez explicite. Utilisez des parenthèses pour indiquer quels opérateurs doivent être évalués en premier. Le tableau suivant liste les opérateurs par ordre de préséance. Plus un opérateur apparaît haut dans la table, plus sa priorité est élevée. Les opérateurs ayant une préséance plus élevée sont évalués avant ceux qui ont une préséance plus faible. Notez que la préséance opérateur de X++ n’est pas la même que celle d’autres langages, comme C# et Java.

Groupes d’opérateurs, par ordre de préséance Opérateurs
Unaire - ~ !
Multiplicatif, décalage, bit par bit ET, bitwise exclusif OU * / % DIV << >> & ^
Additif, inclusif bit par bit OU + - |
Relationnel, égalité < <= == != > >= like as is
Logique (AND,OR) && ||
Conditions ? :

Les opérateurs sur la même ligne ont la même préséance. Si une expression inclut plus d’un de ces opérateurs, elle est évaluée de gauche à droite, sauf si des opérateurs d’affectation sont utilisés. (Les opérateurs d’affectation sont évalués de droite à gauche.) Par exemple, && (logique AND) et || (logique OR) ont la même priorité, et sont évalués de gauche à droite. Par conséquent :

  • 0 && 0 || 1 est égal à 1
  • 1 || 0 && 0 est égal à 0.