最新消息:ww12345678 的部落格重装上线,希望大家继续支持。

X++ Operators

网络文摘 William 1385浏览 0评论

Assignment Operators

An assignment changes the contents of a variable or field.

The X++ assignment operators are shown in the following table. There is no difference between prefixed and postfixed operators.

Operator Description
= Assigns the expression on the right of the equal sign to the variable on the left.
+= Assigns the variable on the left the current variable value plus the expression on the right.
++ Increments the variable by one.
-= Assigns the variable on the left the current variable value minus the expression on the right.
-- Decrements the variable by one.

Assignment Operator Code Examples

// 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. 
}
// Outputplacedhere
Message ( _____ )
Info_a1: The result is 2
Info_a2: etc...

Arithmetic Operators

Use arithmetic operators to perform numeric calculations. All arithmetic operators are dyadic; that is, they work on two operands. The exception is ~, which is unary.

Syntax: expression1 ArithmeticOperator expression2.

The arithmetic operators are as follows:

Operator Description
 << The left shift (<<) operator performs expression2 left shift (a multiplication by 2) on expression1.
>> The right shift (>>) operator performs expression2 right shift (a division by 2) on expression1.
* The multiply (*) operator multiplies expression1 by expression2.
 / The divide (/) operator divides expression1 by expression2.
 DIV The integer division (DIV) operator performs an integer division of expression1 by expression2.
 MOD The integer remainder (MOD) operator returns the remainder of an integer division of expression1 by expression2.
 ~ The not (~) operator, or unary operator, performs a binary not-operation.
 & The binary AND (&) operator performs a binary and-operation on expression1 and expression2.
 ^ The binary XOR (^) operator performs a binary XOR-operation on expression1 and expression2.
 | The binary OR (|) operator performs a binary or-operation on expression1 and expression2.
 + The plus (+) operator adds expression1 to expression2.
 – The minus (-) operator subtracts expression2 from expression1.
 ? The ternary (?) operator takes three expressions: expression1 ? expression2 : expression3. If expression1 is true, expression2 is returned; otherwise, expression3 is returned.

Arithmetic Operators Code Examples

int a;
a = 1 << 4; // Performs 4 left shifts on 1 (1*2*2*2*2). This gives: a=16. // An example of the >> operator.
int b;
b = 16 >> 4;  // Performs 4 right shifts on 16 (16/2/2/2/2). This gives b=1.
int c;
c = 4*5;  // Multiplies 4 by 5. c=20.
int d;
d = 20/5;  // Divides 20 by 5. d=4.

int e;
e = 100 div 21;  // Returns the integer division of 100 by 21. e=4 (4*21 = 84, remainder 16).
int f;
f = 100 mod 21;  // Returns the remainder of the integer division of 100 by 21. f=16.
int g;
g = ~1;  // Binary negates 1. This gives g=-2 (all bits are reversed).
int h;
h = 1 & 3;  // Binary AND. Returns the bits in common in the two integers. h=1;
int i;
i = 1 | 3;  // Binary OR. Return the bits set in either 1 or 3. i=3.
int j;
j = 1 ^ 3;  // Binary XOR. Returns the bits set in 1 and NOT in 3 and vice versa. j=2.
int k;
k = 1 + 3;  // Adds 1 and 3. k=4.
int l;
l = 3 - 1;  // Subtracts 1 from 3. l=2.
int m;
m = (400>4) ? 1 : 5;  // If (400>4) 1 is returned, else 5 is returned. As 400>4, 1 is returned. m=1.

Expression Operators: Is and As for Inheritance

The as and is expression operators control downcast assignments. Downcast assignments involve class or table inheritance. Assignment statements that implicitly downcast can cause errors that are difficult to predict and diagnose. You can use the as keyword to make your downcasts explicit. You can use the is keyword to test whether a downcast is valid at run time.

As Keyword

Use the as keyword for assignments that downcast from a base class variable to a derived class variable. The as keyword tells other programmers and the compiler that you believe the downcast will be valid during run time.

The compiler reports an error for downcast assignment statements that lack the as keyword.

At run time, the as keyword causes the downcast assignment statement to assign null if the downcast is invalid.

This is keyword is often used to safely test whether the as keyword will work.

Code Example for the As Keyword

In the following code example, the DerivedClass class extends the BaseClass class. The code example contains two valid assignments between its basec and derivedc variables. The upcast assignment to basec does not need the as keyword, but the downcast assignment to derivedc does need the as keyword. The following code would compile and run without errors.

    static void AsTestJob33(Args _args)
    {
        // DerivedClass extends BaseClass.
        BaseClass basec;
        DerivedClass derivedc;
        // BottomClass extends DerivedClass.
        BottomClass bottomc;
        derivedc = new DerivedClass();
        // AS is not needed for an upcast assignment like this.
        basec = derivedc;
        // AS is needed 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;
    }

Is Keyword

The is keyword ascertains whether an object is a subtype of a specified class. The is expression returns true if the object is a subtype of the class, or if the object is the same type as the class.

The compiler reports an error if an is keyword expression compares two types where neither is a subtype of the other, and they are not of the same type. The compiler reports a similar error for any plain assignment statement between two types where neither is a subtype of the other, and they are not of the same type.

At run time the type of variable that references the underlying object is irrelevant to the is keyword. The is keyword causes the system to check the object that the variable references, not the declared type of the variable that references the object.

Code Examples for the Is Keyword

The following code examples illustrate the conditions that control whether an is expression returns true or false. The code examples rely on the fact that the Form class and the Query class both extend the TreeNode class.

For this section, the code example precedes the explanations, which are comments.

        Form myForm = new Form();
        info(strFmt("%1", (myForm is Query)));
// The X++ compiler issues an error. 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 extends the TreeNode class, 
// but neither Form nor Query is a subtype of the other.
 
        TreeNode myTreeNode = new TreeNode();
        info(strFmt("%1", (myTreeNode is Form)));
// The Infolog displays 0 during run time, where 0 means false. No supertype 
// object can be considered to also be of its subtype class.
 
        Form myForm;
        info(strFmt("%1", (myForm 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 = new Form();
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 TreeNode)));
// The Infolog displays 1 during run time, where 1 means true. 
// Every subtype is also of its supertype.
 
Form myForm = new Form();
TreeNode myTreeNode;
myTreeNode = myForm; // Upcast.
info(strFmt("%1", (myTreeNode is Form)));
// The Infolog displays 1 during run time, where 1 means true. 
// The type of the underlying object is what matters in the is 
// expression, not the type of the variable that references the object.

Is and As Keywords Code Example

The following code example contains a common use of the is keyword. The as keyword is used after the is keyword verifies that the as keyword will the object. The is and as keywords are uppercase to make them more visible in this example.

static void IsKeywordJob46(Args _args) 
{
    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.

Object Class is a Special Case

The Object class can appear as a special case in inheritance functionality. The compiler has bypasses type checking for assignments to and from variables that are declared of type Object. Some classes inherit from the Object class, some inherit from another class, and some do not inherit from any class. The Dialog class does not inherit from any class, yet the assignment and call statements in the following code example all work. The assignment would fail at compile time if it had been bank4 = dlog3;, because the Bank and Dialog classes have no inheritance relationship to each other.

static void ObjectIsAsJob4(Args _args)
{
    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 display.
    info("Test 4a is finished.");
}

 

The compiler performs only one small check on assignments to a variable that is declared of the Object class. The compiler checks to make sure that the item being assigned to the Object variable is an instance of a class. The compiler does not allow an instance of a table buffer to be assigned to the Object variable. Also, the compiler does not allow primitive data types, such as int or str, to be assigned to the Object variable.

Root Items in Table Inheritance

All tables inherit directly from the Common system table, unless they explicitly inherit from a different table. The Common table cannot be instantiated. The Common table does not exist in the underlying physical database. The Common table inherits from the xRecord class, but only in a special way that is not appropriate for the is keyword or the as keyword.

As Keyword and Tables

When the as keyword is used to perform an invalid downcast among tables, the target variable references an unusable non-null entity. Any attempt to dereference the target variable will cause an error that stops the X++ program.

Is and As Keywords and Extended Data Types

Each extended data type has an Extends property. The style of inheritance that is controlled by this property differs from the style of inheritance that the is and as keywords are designed for.

Relational Operators

The following table lists the relational operators that can be used in X++. All relational operators. except !, are placed between two expressions: expression1 relationalOperator expression2. For example, while (a > 10).

Operator Description
like The like relational operator returns true if expression1 is like expression2.
== The equal relational operator returns true if both expressions are equal.
>= The greater than or equal to relational operator returns true if expression1 is greater than or equal to expression2.
<= The less than or equal to realational operator returns true if expression1 is less than or equal to expression2.
> The greater than relational operator returns true if expression1 is greater than expression2.
< The less than relational operator returns true if expression1 is less than expression2.
!= The not equal relational operator returns true if expression1 is different from (that is, not equal to) expression2.
&& The and relational operator returns true if both expression1 and expression2 are true.
|| The or relational operator returns true if expression1 or expression2 or both are true.
! The not or unary relational operator negates the expression. It returns true if the expression is false or false if the expression is true.

Like Relational Operator (continued)

like can use * as a wildcard for zero or more characters and ? as a wildcard for one character. Expression2 cannot be longer than 1000 characters.

If the expressions that you are comparing contain a file path, you need to include four backslashes between each element. For example:

select * from xRefpaths

    where xRefPaths.Path like “\\\\Classes\\\\AddressSelectForm”

like is evaluated by the underlying SQL, so the result may differ on different installations.

Equal Relational Operator (continued)

When you use == to compare objects, the object references rather than the objects themselves are compared. This may be a problem if you compare two objects that are located on the server and on the client, respectively. In such cases, you should use the equal method in the Object class, which you can override to specify what it means that two objects are equal. If equal is not overridden, the comparison is identical to the one performed by ==.

Relational Operator Code Examples

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

Operator Precedence

The order in which a compound expression is evaluated can be important. For example, (x + y / 100) gives a different result depending on whether the addition or the division is performed first. You can use parentheses ( ) to explicitly tell the compiler how you want an expression to be evaluated. For example, (x + y)/ 100. If you do not explicitly tell the compiler the order that you want operations to be performed in, the order is based on the precedence assigned to the operators. For example, the division operator has a higher precedence than the addition operator. For x + y / 100, the compiler would evaluate y/100 first. So, x + y / 100 is equivalent to x + (y / 100). To make your code easy to read and maintain, be explicit. Indicate with parentheses which operators should be evaluated first.

Order of Operator Precedence

The operators in the following table are listed in precedence order—the higher in the table an operator appears, the higher its precedence. Operators with higher precedence are evaluated before operators with a lower precedence. Note that the operator precedence of X++ is not the same as other languages, for example C# and Java.

Operators in precedence order Syntax
unary operators - ~ !
multiplicative, shift, bitwise AND, bitwise exclusive OR * / % DIV << >> & ^
additive, bitwise inclusive OR + – |
relational, equality < <= == != > >= like as is
logical operators (AND, OR) && ||
conditional ? :

Operators on the same line have equal precedence. If there is more than one of these operators in an expression, the expression is evaluated from left to right unless assignment operators are used (these are evaluated from right to left).

For example, && (logical AND) and || (logical OR) have the same precedence and are evaluated from left to right. This means that:
0&&0||1 == 1, and 1||0&&0 == 0

转载请注明:ww12345678 的部落格 | AX Helper » X++ Operators

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址