共用方式為


X++ 運算子

備註

社區興趣小組現在已從 Yammer 轉移到 Microsoft Viva Engage。 若要加入 Viva Engage 社群並參與最新的討論,請填寫 [ 要求存取財務和營運 Viva Engage 社群 表單 」 ,並選擇您要加入的社群。

本文說明 X++ 中支援的運算子。

指派運算子

指派會變更變數或欄位的值。 下表顯示 X++ 指派運算子。 前綴和後綴運算子之間沒有區別。

Operator Description
= 將等號右側的運算式指派給左側的變數。
+= 將目前變數值加上右側的運算式指派給左側的變數。
++ 將變數遞增 1。
-= 將目前變數值減去右側的運算式指派給左側的變數。
-- 將變數遞減 1。

賦值運算子的程式碼範例

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

算術運算子

您可以使用算術運算子來執行數值計算。 大多數運算子都是二進位的,採用兩個操作數。 然而, not~) 運算子是一元的,並且只接受一個運算元。 二進位運算子的語法: expression1ArithmeticOperatorexpression2 一元運算子的語法: ArithmeticOperatorexpression1

Operator Description
<< 左移運算子會在 expression1 上執行 expression2 左移 (乘以 2)。
>> 右移運算子在 expression1 上執行 expression2 右移 (除以 2)。
* 乘法運算子會將 expression1 乘以 expression2
/ 除法運算子會將 expression1 除以 expression2
DIV 整數除法運算子會執行 expression1 乘以 expression2 的整數除法。
MOD 整數餘數運算子會傳回 expression1 除以 expression2 的整數除法的餘數。
~ not 運算子或一元運算子會執行二進位 not 運算。
& 二進位 AND 運算子會對 expression1expression2 執行二進位 AND 運算。
^ 二進位 XOR 運算子會對 expression1expression2 執行二進位 XOR 運算。
| 二進位 OR 運算子會對 expression1expression2 執行二進位或運算。
+ 加號運算子會將 expression1 新增至 expression2
- 減號運算子會從 expression1 中減去 expression2
? 三元運算子採用三個運算式:expression1表達式 2表達式 3。 如果 expression1 為 true,則會傳回 expression2 。 否則,會傳回 expression3

算術運算子的程式碼範例

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.

運算式運算子

asis運算式運算子控制向下轉換指派。 Downcast 指派涉及類別或資料表繼承。 隱含縮減的指派陳述式可能會導致難以預測及診斷的錯誤。 您可以使用 as 關鍵字來明確地表達您的貶低。 您可以使用 is 關鍵字來測試向下轉換在執行時期是否有效。

as 關鍵字

將關鍵字 as 用於從基底類別變數向下轉換至衍生類別變數的指派。 as關鍵字會告訴其他程式設計師及編譯器,您相信向下轉換在執行時期有效。

  • 編譯器會針對缺少 as 關鍵字的 downcast 指派陳述式報告錯誤。
  • 在執行階段,關鍵字 as 會導致 downcast 指派陳述式 null 在 downcast 無效時指派。
  • 這個 is 關鍵字通常用於安全地測試關鍵字 as 是否有效。

as 關鍵字的程式碼範例

在下列程式碼範例中, DerivedClass 類別會擴充 BaseClass 類別。 程式碼範例包含其 basec 變數與 衍生 dc 變數之間的兩個有效指派。 basecas 的向下轉換指派不需要關鍵字,但 derivedc 的向下轉換指派確實需要as關鍵字。 以下程式碼將編譯並運行而不會出錯。

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

is 關鍵字

關鍵字會 is 驗證物件是否是指定類別的子類型。 is如果物件是類別的子類型,或物件與類別的類型相同,則運算式會傳回 true。 如果關鍵字運算式比較兩種類型,但這兩種類型都不是另一種類型的子類型,而且它們不屬於相同類型,則 is 編譯器會報告錯誤。 編譯器會針對兩種類型之間的任何純賦值陳述式報告類似的錯誤,其中兩種類型都不是另一種類型的子類型,而且它們不屬於相同的類型。 在執行階段,參照基礎物件的變數類型與 is 關鍵字無關。 is關鍵字會導致系統驗證變數所參照的物件,而不是參照物件之變數的宣告類型。

is 關鍵字的程式碼範例

下列程式碼範例說明控制運算式是否 is 傳回 truefalse 的條件。 程式碼範例取決於 Form 類別和 Query 類別都擴充 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)));

is 和 as 關鍵字的程式碼範例

下列程式碼範例包含關鍵字的 is 一般用法。 as關鍵字在關鍵字驗證is關鍵字會成功之後as使用。 在此範例中, isas 關鍵字為大寫,以使其更明顯。

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.

物件類別作為特殊案例

Object 類別可以顯示為繼承功能中的特殊情況。 編譯器會略過類型檢查,以進行與宣告為 Object 類型的變數之間的指派。 有些類別繼承自 Object 類別,有些類別繼承自另一個類別,有些類別不繼承自任何類別。 雖然 Dialog 類別不會繼承自任何類別,但下列程式碼範例中的 assignment 和 call 陳述式可以運作。 但是,如果賦值是 bank4 = dlog3;,則會在編譯時失敗,因為 BankDialog 類別彼此之間沒有繼承關係。 編譯器只會對宣告為 Object 類別之變數的指派執行一個小型驗證。 編譯器會驗證指派給 Object 變數的項目是否是類別的實例。 編譯器不允許將資料表緩衝區的實例指派給 Object 變數。 此外,編譯器不允許將基本資料類型(例如 intstr)指派給 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

所有資料表都會直接繼承自「通用系統資料表」,除非它們明確繼承自不同的資料表。 無法具現化 Common 資料表。 它不存在於基礎實體資料庫中。 Common 資料表繼承自 xRecord 類別,但採用不適合關鍵字或is關鍵字的as特殊方式。 當關鍵字用來在表格之間執行無效的向下轉換時 as ,目標變數會參照無法使用的非空值實體。 任何取消參照目標變數的嘗試都會導致停止程式的錯誤。

is 和 as 關鍵字和擴展數據類型

每個擴充資料類型都有一個 Extends 屬性。 此屬性控制的繼承樣式與 和 isas 關鍵字所設計的繼承樣式不同。

關聯式運算子

下表列出可在 X++ 中使用的關聯式運算子。 大多數運算子都是二進位的,採用兩個操作數。 然而, not!) 運算子是一元的,並且只接受一個運算元。 二進位運算子的語法: expression1relationalOperatorexpression2 一元運算子的語法: relationalOperatorexpression1

Operator Description
like 如果 expression1 類似 expression2,則 like 關聯運算子會傳回 true
== 如果兩個運算式相等,相 關聯式運算子會傳回 true
>= 如果 expression1 大於或等於 expression2,則大於或等於關聯式運算子會傳回 true
<= 如果 expression1 小於或等於 expression2,則小於或等於關聯式運算子會傳回 true
> 如果 expression1 大於 expression2,則大於關聯運算子會傳回 true
< 如果 expression1 小於 expression2,則小於關聯運算子會傳回 true
!= 如果 expression1 與 expression2 不同 (亦即,如果不等於) expression2,則不相等的關聯式運算子會傳回 true
&& 如果 expression1expression2 都為 true,則 and 關聯運算子會傳回 true
|| 如果 expression1expression2 為 true,或兩者均為 true,則 or 關聯運算子會傳回 true
! not一元關係運算子會否定運算式。 如果運算式為 false,則傳回 true ,如果運算式為 true,則傳回 false

like 運算子

運算子 like 可以作為 * 零個或多個字元的萬用字元,以及 ? 作為一個字元的萬用字元。 運算元的長度上限為 1,000 個字元。 like運算子是由基礎 SQL 評估,因此結果在不同的安裝上可能會有所不同。 如果您要比較的運算式包含檔案路徑,則必須在每個元素之間包含四個反斜線,如下列範例所示。

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

等於 (==) 運算子

當您使用 equal==) 運算子來比較物件時,會比較物件參照,而不是物件本身。 如果您比較兩個物件,其中一個位於伺服器上,另一個位於用戶端上,則此行為可能會導致問題。 在這些情況下,您應該在 Object 類別中使用 equal 方法。 您可以覆寫這個方法,以指定兩個物件相等的意義。 如果您未置換 equal 方法,則比較與 equal==) 運算子所完成的比較相同。

關聯式運算子的程式碼範例

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

運算子優先順序

評估複合運算式的順序可能很重要。 例如,給 (x + y / 100) 出不同的結果,具體取決於是先進行加法還是除法。 您可以使用括號 (()) 明確告訴編譯器它應該如何評估運算式。 例如,您可以指定 (x + y) / 100。 如果您未明確告知編譯器您想要執行作業的順序,則順序是以指派給運算子的優先順序為基礎。 例如,除法運算子的優先順序高於加法運算子。 因此,對於表達式 x + y / 100,編譯器首先求值 y / 100 。 換句話說, x + y / 100 相當於 x + (y / 100)。 為了使您的程式碼易於閱讀和維護,請明確。 使用括弧來指出應該先評估哪些運算子。 下表依優先順序列出運算子。 運算子在表格中顯示得越高,其優先順序就越高。 具有較高優先順序的運算子會在優先順序較低的運算子之前進行評估。 請注意,X++ 的運算子優先順序與其他語言 (例如 C# 和 Java) 的運算子優先順序不同。

運算子群組 (依優先順序) 運營商
Unary - ~ !
乘法、移位、按位元 AND、位元排他 OR * / % DIV << >> & ^
加法、位元包含 OR + - |
關係、平等 < <= == != > >= like as is
邏輯 (ANDOR && ||
Conditional ? :

同一行上的運算子具有相同的優先順序。 如果運算式包含多個這些運算子,則會從左到右評估,除非使用賦值運算子。 (賦值運算子會從右到左評估。例如, && (邏輯 AND) 和 || (邏輯 OR) 具有相同的優先順序,並且從左到右評估。 Therefore:

  • 0 && 0 || 1 等於 1
  • 1 || 0 && 0 等於 0