Partilhar via


Operadores X++

Observação

Os grupos de interesse da comunidade passaram do Yammer para o Microsoft Viva Engage. Para participar de uma comunidade Viva Engage e participar das últimas discussões, preencha o formulário Solicitar acesso ao Finance and Operations Viva Engage Community e escolha a comunidade à qual deseja participar.

Este artigo descreve os operadores suportados no X++.

Operadores de atribuição

Uma atribuição altera o valor de uma variável ou campo. A tabela a seguir mostra os operadores de atribuição X++. Não há diferença entre operadores de prefixo e postfix.

Operator Description
= Atribua a expressão à direita do sinal de igual à variável à esquerda.
+= Atribua o valor da variável atual mais a expressão à direita à variável à esquerda.
++ Incremente a variável em 1.
-= Atribua o valor da variável atual menos a expressão à direita à variável à esquerda.
-- Decréscimo da variável em 1.

Exemplos de código para operadores de atribuição

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

Você usa operadores aritméticos para executar cálculos numéricos. A maioria dos operadores são binários e usam dois operandos. No entanto, o operador not (~) é unário e usa apenas um operando. Sintaxe para operadores binários: expression1ArithmeticOperatorexpression2 Sintaxe para operadores unários: ArithmeticOperatorexpression1

Operator Description
<< O operador de deslocamento à esquerda executa expression2 left shift (multiplicação por 2) em expression1.
>> O operador de deslocamento para a direita executa expression2 right shift (divisão por 2) em expression1.
* O operador multiplicaexpression1 por expression2.
/ O operador divideexpression1 por expression2.
DIV O operador de divisão inteira executa uma divisão inteira de expression1 por expression2.
MOD O operador integer restante retorna o restante de uma divisão inteira de expression1 por expression2.
~ O operador não , ou operador unário, executa uma operação binária não.
& O operador binário AND executa um binário e uma operação em expression1 e expression2.
^ O operador XOR binário executa uma operação XOR binária em expression1 e expression2.
| O operador binário OR executa um binário ou operação em expression1 e expression2.
+ O operador plus adiciona expression1 a expression2.
- O operador menos subtrai expression2 de expression1.
? O operador ternário toma três expressões: expression1 ? expressão2 : expressão3. Se expression1 for true, expression2 será retornada. Caso contrário, expression3 será retornado.

Exemplos 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 expressão

Os as operadores e is expressão controlam atribuições downcast. As atribuições downcast envolvem herança de classe ou tabela. Instruções de atribuição que implicitamente downcast podem causar erros que são difíceis de prever e diagnosticar. Você pode usar a as palavra-chave para tornar seus downcasts explícitos. Você pode usar a is palavra-chave para testar se um downcast é válido em tempo de execução.

A palavra-chave as

Use a as palavra-chave para atribuições que fazem downcast de uma variável de classe base para uma variável de classe derivada. A as palavra-chave diz a outros programadores e ao compilador que você acredita que o downcast será válido durante o tempo de execução.

  • O compilador relata um erro para instruções de atribuição downcast que não possuem a as palavra-chave.
  • Em tempo de execução, a as palavra-chave faz com que a instrução de atribuição downcast seja atribuída null se a downcast não for válida.
  • Essa is palavra-chave é frequentemente usada para testar com segurança se a as palavra-chave funcionará.

Exemplo de código para a palavra-chave as

No exemplo de código a seguir, a classe DerivedClass estende a classe BaseClass . O exemplo de código contém duas atribuições válidas entre suas variáveis basec e derivedc . A atribuição de upcast para basec não requer a as palavra-chave, mas a atribuição downcast para derivedc requer a as palavra-chave. O código a seguir será compilado e executado sem erros.

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

A palavra-chave is

A is palavra-chave verifica se um objeto é um subtipo de uma classe especificada. A is expressão retorna true se o objeto for um subtipo da classe ou se o objeto for do mesmo tipo que a classe. O compilador relata um erro se uma is expressão de palavra-chave compara dois tipos, mas nenhum tipo é um subtipo do outro, e eles não são do mesmo tipo. O compilador relata um erro semelhante para qualquer instrução de atribuição simples entre dois tipos, onde nenhum tipo é um subtipo do outro, e eles não são do mesmo tipo. Em tempo de execução, o tipo de variável que faz referência ao objeto subjacente é irrelevante para a is palavra-chave. A is palavra-chave faz com que o sistema verifique o objeto ao qual a variável faz referência, não o tipo declarado da variável que faz referência ao objeto.

Exemplos de código para a palavra-chave is

Os exemplos de código a seguir ilustram as condições que controlam se uma is expressão retorna true ou false. Os exemplos de código dependem do fato de que a classe Form e a classe Query estendem a 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)));

Exemplo de código para o is e como palavras-chave

O exemplo de código a seguir contém um uso típico da is palavra-chave. A as palavra-chave é usada depois que a is palavra-chave verifica se a as palavra-chave terá êxito. Neste exemplo, as palavras-chave e is são maiúsculas as para torná-las mais visíveis.

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 de objeto como um caso especial

A classe Object pode aparecer como um caso especial na funcionalidade de herança. O compilador ignora a verificação de tipo para atribuições de e para variáveis que são declaradas como do tipo Object. Algumas classes herdam da classe Object , algumas classes herdam de outra classe e algumas classes não herdam de nenhuma classe. Embora a classe Dialog não herde de nenhuma classe, as instruções de atribuição e chamada no exemplo de código a seguir funcionam. No entanto, se a atribuição for bank4 = dlog3;, ela falhará em tempo de compilação, porque as classes Bank e Dialog não têm nenhuma relação de herança entre si. O compilador executa apenas uma pequena validação em atribuições para uma variável que é declarada como sendo da classe Object . O compilador verifica se o item que está sendo atribuído à variável Object é uma instância de uma classe. O compilador não permite que uma instância de um buffer de tabela seja atribuída à variável Object . Além disso, o compilador não permite que tipos de dados primitivos, como int ou str, sejam atribuídos à variável 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 as tabelas herdam diretamente da tabela Common system, a menos que herdem explicitamente de uma tabela diferente. A tabela Comum não pode ser instanciada. Ele não existe no banco de dados físico subjacente. A tabela Common herda da classe xRecord , mas de uma maneira especial que não é apropriada para a is palavra-chave ou a as palavra-chave. Quando a as palavra-chave é usada para executar um downcast inválido entre tabelas, a variável de destino faz referência a uma entidade não nula inutilizável. Qualquer tentativa de cancelar a referência da variável de destino causará um erro que interrompe o programa.

O é e como palavras-chave e tipos de dados estendidos

Cada tipo de dados estendido tem uma propriedade Extends . O estilo de herança que essa propriedade controla difere do estilo de herança para o qual as palavras-chave e is foram as projetadas.

Operadores relacionais

A tabela a seguir lista os operadores relacionais que podem ser usados no X++. A maioria dos operadores são binários e usam dois operandos. No entanto, o operador not (!) é unário e usa apenas um operando. Sintaxe para operadores binários: expression1relationalOperatorexpression2 Sintaxe para operadores unários: relationalOperatorexpression1

Operator Description
like O operador relacional like retorna true se expression1 for como expression2.
== O operador relacional igual retorna true se ambas as expressões forem iguais.
>= O operador relacional maior ou igual retornatrue se expression1 for maior ou igual a expression2.
<= O operador relacional menor ou igual aretornará true se expression1 for menor ou igual a expression2.
> O operador maior que relacional retorna true se expression1 for maior que expression2.
< O operador menos relacional retornatrue se expression1 for menor que expression2.
!= O operador relacional não igual retorna true se expression1 difere de (isto é, se não é igual a) expression2.
&& O operador relacional e retorna true se expression1 e expression2 forem true.
|| O operador relacional ou retorna true se expression1 ou expression2 for true, ou se ambos forem true.
! O operador relacional nãoou unário nega a expressão. Ele retorna true se a expressão for false e false se a expressão for true.

O operador similar

O like operador pode usar * como um caractere curinga para zero ou mais caracteres e como um caractere curinga para um caractere ? . O comprimento máximo do operando é de 1.000 caracteres. O like operador é avaliado pelo SQL subjacente, portanto, o resultado pode diferir em instalações diferentes. Se as expressões que você está comparando contiverem um caminho de arquivo, você deverá incluir quatro barras invertidas entre cada elemento, conforme mostrado no exemplo a seguir.

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

O operador igual (==)

Quando você usa o operador igual (==) para comparar objetos, as referências de objeto são comparadas, não os objetos em si. Esse comportamento pode causar problemas se você comparar dois objetos, um dos quais está localizado no servidor e o outro está localizado no cliente. Nesses casos, você deve usar o método equal na classe Object . Você pode substituir esse método para especificar o que significa para dois objetos serem iguais. Se você não substituir o método equal , a comparação será idêntica à comparação feita pelo operador equal (==).

Exemplos de código para operadores relacionais

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

Precedência dos operadores

A ordem em que uma expressão composta é avaliada pode ser importante. Por exemplo, (x + y / 100) dá um resultado diferente, dependendo se a adição ou a divisão é feita primeiro. Você pode usar parênteses (()) para dizer explicitamente ao compilador como ele deve avaliar uma expressão. Por exemplo, você pode especificar (x + y) / 100. Se você não informar explicitamente ao compilador a ordem em que deseja que as operações sejam feitas, a ordem será baseada na precedência atribuída aos operadores. Por exemplo, o operador de divisão tem maior precedência do que o operador de adição. Portanto, para a expressão x + y / 100, o compilador avalia y / 100 primeiro. Em outras palavras, x + y / 100 é equivalente a x + (y / 100). Para tornar seu código fácil de ler e manter, seja explícito. Use parênteses para indicar quais operadores devem ser avaliados primeiro. A tabela a seguir lista os operadores em ordem de precedência. Quanto mais alto um operador aparecer na tabela, maior será a sua precedência. Os operadores que têm maior precedência são avaliados antes dos operadores que têm menor precedência. Observe que a precedência do operador do X++ não é a mesma que a precedência do operador de outras linguagens, como C# e Java.

Grupos de operadores, por ordem de precedência Operadores
Unary - ~ !
Multiplicativo, shift, bitwise AND, bitwise exclusivo OU * / % DIV << >> & ^
Aditivo, bitwise inclusive OU + - |
Relacional, igualdade < <= == != > >= like as is
Lógica (E,OR) && ||
Conditional ? :

Os operadores da mesma linha têm igual precedência. Se uma expressão incluir mais de um desses operadores, ela será avaliada da esquerda para a direita, a menos que operadores de atribuição sejam usados. (Os operadores de atribuição são avaliados da direita para a esquerda.) Por exemplo, && (lógico AND) e || (lógico OR) têm a mesma precedência e são avaliados da esquerda para a direita. Therefore:

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