Compartilhar via


Operadores de X++

Observação

Grupos de interesse da comunidade mudaram do Yammer para o Microsoft Viva Engage. Para ingressar em uma comunidade do Viva Engage e participar das discussões mais recentes, preencha o formulário Solicitar acesso às Finanças e Operações viva engage community e escolha a comunidade que você deseja ingressar.

Este artigo descreve os operadores com suporte 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 os 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.
-- Decremente a variável por 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 é binária e usa dois operandos. No entanto, o operador não (~) é unário e usa apenas um operando. Sintaxe para operadores binários: expression1AithmeticOperatorexpression2 Sintaxe for unary operators: AithmeticOperatorexpression1

Operator Description
<< O operador de deslocamento esquerdo executa a expressão2 shift esquerdo (multiplicação por 2) na expressão1.
>> O operador de deslocamento para a direita executa o deslocamento de expressão2 para a direita (divisão por 2) na expressão1.
* O operador multiplicador multiplica a expressão1 por expression2.
/ O operador dividea expressão1 por expression2.
DIV O operador de divisão inteiro executa uma divisão de inteiros de expression1 por expression2.
MOD O operador de restante inteiro retorna o restante de uma divisão inteiro de expression1 por expression2.
~ O operador não , ou unário, executa uma operação binária não.
& O operador AND binário 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 OR binário executa um binário ou operação em expression1 e expression2.
+ O operador de adição adiciona expressão1 à expressão2.
- O operador de subtração subtrai a expressão2 da expressão1.
? O operador ternário usa três expressões: expression1 ? expression2 : expression3. Se expression1 for true, expression2 será retornado. Caso contrário, a expressão3 será retornada.

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 de expressão e is de expressão controlam atribuições de downcast. As atribuições de downcast envolvem herança de classe ou tabela. Instruções de atribuição que implicitamente abatidas podem causar erros 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 como

Use a as palavra-chave para atribuições que reduzem de uma variável de classe base para uma variável de classe derivada. A as palavra-chave informa 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 de downcast que não têm a as palavra-chave.
  • Em tempo de execução, a as palavra-chave faz com que a instrução de atribuição downcast atribua null se o downcast não for válido.
  • Essa is palavra-chave geralmente é usada para testar com segurança se a as palavra-chave funcionará.

Exemplo de código para a palavra-chave como

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 base ederivadas . A atribuição de upcast para basec não requer a as palavra-chave, mas a atribuição de downcast para derivada 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 é

A is palavra-chave verifica se um objeto é um subtipo de uma classe especificada. A is expressão retornará true se o objeto for um subtipo da classe ou se o objeto for do mesmo tipo que a classe. O compilador relatará um erro se uma is expressão de palavra-chave comparar dois tipos, mas nenhum dos tipos for um subtipo do outro e eles não forem do mesmo tipo. O compilador relata um erro semelhante para qualquer instrução de atribuição simples entre dois tipos, em que nenhum dos tipos é 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 que 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 expressão is 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 as palavras-chave is e as

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 as as palavras-chave são maiúsculas 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 Objeto. 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 herda 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á no momento da compilação, pois as classes Banco e Caixa de Diálogo não têm relação de herança entre si. O compilador executa apenas uma pequena validação em atribuições para uma variável 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 do sistema Comum, 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 Comum 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 fazer referência à variável de destino causará um erro que interrompe o programa.

As palavras-chave is e como tipos de dados estendidos

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

Operadores relacionais

A tabela a seguir lista os operadores relacionais que podem ser usados no X++. A maioria dos operadores é binária e usa dois operandos. No entanto, o operador não (!) é 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 semelhante retornará true se expression1 for como expression2.
== O operador relacional igual retornará true se ambas as expressões forem iguais.
>= O operador maior ou igual a relacional retornará true se expression1 for maior ou igual a expression2.
<= O operador menor ou igual a relacional retornará true se expression1 for menor ou igual a expression2.
> O operador relacional maior que retorna true se expression1 for maior que expression2.
< O operador menor que relacional retornará true se expression1 for menor que expression2.
!= O operador relacional não igual retornará true se expression1 for diferente (ou seja, se não for igual a) expression2.
&& O operador relacional e o operador relacional retornarão true se expression1 e expression2 forem verdadeiros.
|| O operador ou relacional retornará true se expression1 ou expression2 for true ou se ambos forem verdadeiros.
! O operador relacional não ou unário nega a expressão. Ela retornará true se a expressão for false e false se a expressão for verdadeira.

O operador like

O like operador pode usar * como caractere curinga para zero ou mais caracteres e ? como 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 ser diferente 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 próprios objetos. Esse comportamento poderá causar problemas se você comparar dois objetos, um deles localizado no servidor e outro localizado no cliente. Nesses casos, você deve usar o método igual na classe Object . Você pode substituir esse método para especificar o que significa que dois objetos sejam iguais. Se você não substituir o método igual , a comparação será idêntica à comparação feita pelo operador igual (==).

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 do operador

A ordem em que uma expressão composta é avaliada pode ser importante. Por exemplo, (x + y / 100) fornece um resultado diferente, dependendo se a adição ou a divisão é feita primeiro. Você pode usar parênteses (()) para informar 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 precedência maior do que o operador de adição. Portanto, para a expressão x + y / 100, o compilador é avaliado y / 100 primeiro. Em outras palavras, x + y / 100 é equivalente a x + (y / 100). Para facilitar a leitura e a manutenção do código, 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 maior for o operador exibido na tabela, maior será sua precedência. Os operadores com precedência mais alta são avaliados antes dos operadores que têm precedência inferior. Observe que a precedência do operador X++ não é a mesma que a precedência do operador de outras linguagens, como C# e Java.

Grupos de operadores, em ordem de precedência Operadores
Unary - ~ !
Multiplicativo, shift, AND bit a bit, OR exclusivo bit a bit * / % DIV << >> & ^
ADITIVO, or inclusivo bit a bit + - |
Relacional, igualdade < <= == != > >= like as is
Lógico (AND, OR) && ||
Condicional ? :

Operadores na mesma linha têm precedência igual. Se uma expressão incluir mais de um desses operadores, ela será avaliada da esquerda para a direita, a menos que os 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.