Compartir a través de


Operadores de X++

Nota:

Los grupos de interés de la comunidad ahora se han movido de Yammer a Microsoft Viva Engage. Para unirse a una comunidad viva Engage y participar en las últimas discusiones, rellene el formulario Solicitar acceso a Finance and Operations Viva Engage Community y elija la comunidad a la que desea unirse.

En este artículo se describen los operadores admitidos en X++.

Operadores de asignación

Una asignación cambia el valor de una variable o campo. En la tabla siguiente se muestran los operadores de asignación X++. No hay ninguna diferencia entre los operadores de prefijo y postfijo.

Operator Description
= Asigne la expresión a la derecha del signo igual a la variable de la izquierda.
+= Asigne el valor de variable actual más la expresión de la derecha a la variable de la izquierda.
++ Incremente la variable en 1.
-= Asigne el valor de variable actual menos la expresión de la derecha a la variable de la izquierda.
-- Disminuir la variable en 1.

Ejemplos de código para operadores de asignación

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

Operadores aritméticos

Los operadores aritméticos se usan para realizar cálculos numéricos. La mayoría de los operadores son binarios y toman dos operandos. Sin embargo, el operador not (~) es unario y solo toma un operando. Sintaxis para operadores binarios: expression1ArithmeticOperatorexpression2 Sintaxis para operadores unarios: ArithmeticOperatorexpression1

Operator Description
<< El operador de desplazamiento izquierdo realiza el desplazamiento izquierdo expression2 (multiplicación por 2) en expression1.
>> El operador de desplazamiento a la derecha realiza el desplazamiento a la derecha de expression2 (división por 2) en expression1.
* El operador de multiplicación multiplica expression1 por expression2.
/ El operador divideexpression1 por expression2.
DIV El operador de división de enteros realiza una división entera de expression1 by expression2.
MOD El operador de resto entero devuelve el resto de una división de enteros de expression1 por expression2.
~ El operador not , o un operador unario, realiza una operación binaria no.
& El operador BINARY AND realiza una operación binaria y en expression1 y expression2.
^ El operador XOR binario realiza una operación XOR binaria en expression1 y expression2.
| El operador OR binario realiza una operación binaria o en expression1 y expression2.
+ El operador más agrega expression1 a expression2.
- El operador menos resta expression2 de expression1.
? El operador ternario toma tres expresiones: expression1 ? expression2 : expression3. Si expression1 es true, se devuelve expression2 . De lo contrario, se devuelve expression3 .

Ejemplos de código para operadores aritméticos

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.

Operadores de expresión

Los as operadores de expresión y is controlan las asignaciones de difusión descendente. Las asignaciones de difusión descendente implican la herencia de clases o tablas. Las instrucciones de asignación que se aplican implícitamente a la difusión a un nivel inferior pueden provocar errores difíciles de predecir y diagnosticar. Puede usar la as palabra clave para hacer explícitas las downcasts. Puede usar la is palabra clave para probar si una difusión descendente es válida en tiempo de ejecución.

Palabra clave as

Use la as palabra clave para las asignaciones que reducen la difusión de una variable de clase base a una variable de clase derivada. La as palabra clave indica a otros programadores y al compilador que cree que la difusión descendente será válida durante el tiempo de ejecución.

  • El compilador notifica un error para las instrucciones de asignación de difusión descendente que carecen de la as palabra clave .
  • En tiempo de ejecución, la as palabra clave hace que la instrucción de asignación de difusión descendente se asigne null si la difusión hacia abajo no es válida.
  • Esta is palabra clave se usa a menudo para probar de forma segura si la as palabra clave funcionará.

Ejemplo de código para la palabra clave as

En el ejemplo de código siguiente, la clase DerivedClass extiende la clase BaseClass . El ejemplo de código contiene dos asignaciones válidas entre sus variables basec y derivadas . La asignación de difusión vertical a basec no requiere la as palabra clave , pero la asignación de difusión a derivada requiere la as palabra clave . El código siguiente se compilará y ejecutará sin errores.

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

La palabra clave is

La is palabra clave comprueba si un objeto es un subtipo de una clase especificada. La is expresión devuelve true si el objeto es un subtipo de la clase o si el objeto es el mismo tipo que la clase . El compilador notifica un error si una is expresión de palabra clave compara dos tipos, pero ninguno de ellos es un subtipo del otro y no es del mismo tipo. El compilador notifica un error similar para cualquier instrucción de asignación sin formato entre dos tipos, donde ninguno de ellos es un subtipo del otro y no es del mismo tipo. En tiempo de ejecución, el tipo de variable que hace referencia al objeto subyacente es irrelevante para la is palabra clave . La is palabra clave hace que el sistema compruebe el objeto al que hace referencia la variable, no el tipo declarado de la variable que hace referencia al objeto.

Ejemplos de código para la palabra clave is

En los ejemplos de código siguientes se muestran las condiciones que controlan si una is expresión devuelve true o false. Los ejemplos de código dependen del hecho de que la clase Form y la clase Query amplían la clase 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)));

Ejemplo de código de es y como palabras clave

El ejemplo de código siguiente contiene un uso típico de la is palabra clave . La as palabra clave se usa después de que la is palabra clave compruebe que la as palabra clave se realizará correctamente. En este ejemplo, las is palabras clave y as están en mayúsculas para que sean más 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.

Clase de objeto como caso especial

La clase Object puede aparecer como un caso especial en la funcionalidad de herencia. El compilador omite la comprobación de tipos para las asignaciones hacia y desde variables declaradas como de tipo Object. Algunas clases heredan de la clase Object , algunas clases heredan de otra clase y algunas clases no heredan de ninguna clase. Aunque la clase Dialog no hereda de ninguna clase, funcionan las instrucciones de asignación y llamada en el siguiente ejemplo de código. Sin embargo, si la asignación es bank4 = dlog3;, se producirá un error en tiempo de compilación, ya que las clases Bank y Dialog no tienen ninguna relación de herencia entre sí. El compilador solo realiza una validación pequeña en las asignaciones de una variable declarada como de la clase Object . El compilador comprueba que el elemento que se asigna a la variable Object es una instancia de una clase . El compilador no permite asignar una instancia de un búfer de tabla a la variable Object . Además, el compilador no permite asignar tipos de datos primitivos, como int o str, a la variable Object .

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

Todas las tablas heredan directamente de la tabla common system, a menos que hereden explícitamente de una tabla diferente. No se puede crear una instancia de la tabla Common. No existe en la base de datos física subyacente. La tabla Common hereda de la clase xRecord , pero de forma especial que no es adecuada para la is palabra clave o la as palabra clave . Cuando la as palabra clave se usa para realizar una difusión descendente no válida entre tablas, la variable de destino hace referencia a una entidad que no acepta valores NULL inutilizable. Cualquier intento de anular la referencia a la variable de destino provocará un error que detenga el programa.

es y como palabras clave y tipos de datos extendidos

Cada tipo de datos extendido tiene una propiedad Extends . El estilo de herencia para el que controla esta propiedad difiere del estilo de herencia para el que están diseñadas las is palabras clave y as .

Operadores relacionales

En la tabla siguiente se enumeran los operadores relacionales que se pueden usar en X++. La mayoría de los operadores son binarios y toman dos operandos. Sin embargo, el operador not (!) es unario y solo toma un operando. Sintaxis para operadores binarios: expression1relationalOperatorexpression2 Sintaxis para operadores unarios: relationalOperatorexpression1

Operator Description
like El operador relacional like devuelve true si expression1 es como expression2.
== El operador relacional igual devuelve true si ambas expresiones son iguales.
>= El operador relacional mayor o igual quedevuelve true si expression1 es mayor o igual que expression2.
<= El operador relacional menor o igual quedevuelve true si expression1 es menor o igual que expression2.
> El operador relacional mayor que devuelve true si expression1 es mayor que expression2.
< El operador relacional menor que devuelve true si expression1 es menor que expression2.
!= El operador relacional no igual devuelve true si expression1 difiere de (es decir, si no es igual a) expression2.
&& El operador relacional y devuelve true si expression1 y expression2 son true.
|| El operador relacional o devuelve true si expression1 o expression2 es true o si ambos son true.
! El operador relacional no o unario niega la expresión. Devuelve true si la expresión es false y false si la expresión es true.

Operador like

El like operador puede usar * como carácter comodín para cero o más caracteres y ? como carácter comodín para un carácter. La longitud máxima del operando es de 1000 caracteres. El like operador se evalúa mediante el SQL subyacente, por lo que el resultado puede diferir en diferentes instalaciones. Si las expresiones que está comparando contienen una ruta de acceso de archivo, debe incluir cuatro barras diagonales inversas entre cada elemento, como se muestra en el ejemplo siguiente.

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

Operador equal (==)

Cuando se usa el operador igual (==) para comparar objetos, se comparan las referencias de objeto, no los propios objetos. Este comportamiento puede causar problemas si compara dos objetos, uno de los cuales se encuentra en el servidor y el otro de los cuales se encuentra en el cliente. En estos casos, debe usar el método igual en la clase Object . Puede invalidar este método para especificar lo que significa que dos objetos sean iguales. Si no invalida el método igual , la comparación es idéntica a la comparación realizada por el operador igual (==).

Ejemplos de código para operadores relacionales

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

Precedencia del operador

El orden en el que se evalúa una expresión compuesta puede ser importante. Por ejemplo, (x + y / 100) proporciona un resultado diferente, dependiendo de si la suma o la división se realiza primero. Puede usar paréntesis (()) para indicar explícitamente al compilador cómo debe evaluar una expresión. Por ejemplo, puede especificar (x + y) / 100. Si no indica explícitamente al compilador el orden en que desea que se realicen las operaciones, el orden se basa en la prioridad asignada a los operadores. Por ejemplo, el operador de división tiene mayor prioridad que el operador de suma. Por lo tanto, para la expresión x + y / 100, el compilador se evalúa y / 100 primero. En otras palabras, x + y / 100 es equivalente a x + (y / 100). Para que el código sea fácil de leer y mantener, sea explícito. Use paréntesis para indicar qué operadores se deben evaluar primero. En la tabla siguiente se enumeran los operadores en orden de prioridad. Cuanto mayor aparezca un operador en la tabla, mayor será su prioridad. Los operadores que tienen mayor prioridad se evalúan antes de los operadores que tienen menor prioridad. Tenga en cuenta que la prioridad del operador de X++ no es la misma que la prioridad del operador de otros lenguajes, como C# y Java.

Grupos de operadores, en orden de prioridad Operadores
Unary - ~ !
Multiplicativo, desplazamiento, AND bit a bit, OR exclusivo bit a bit * / % DIV << >> & ^
OR aditivo, inclusivo bit a bit + - |
Relacional, igualdad < <= == != > >= like as is
Lógico (AND, OR) && ||
Condicional ? :

Los operadores de la misma línea tienen la misma prioridad. Si una expresión incluye más de uno de estos operadores, se evalúa de izquierda a derecha, a menos que se usen operadores de asignación. (Los operadores de asignación se evalúan de derecha a izquierda). Por ejemplo, && (lógico AND) y || (lógico OR) tienen la misma prioridad y se evalúan de izquierda a derecha. Therefore:

  • 0 && 0 || 1 es igual a 1
  • 1 || 0 && 0 es igual a 0.