Nota
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare ad accedere o a cambiare directory.
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare a cambiare directory.
Nota
I gruppi di interesse della community sono ora passati da Yammer a Microsoft Viva Engage. Per entrare a far parte di una community Viva Engage e partecipare alle discussioni più recenti, compila il modulo Richiedi l'accesso alla community Viva Engage per Finance and Operations e scegli la community a cui vuoi unirti.
Questo articolo descrive gli operatori supportati in X++.
Operatori di assegnazione
Un'assegnazione modifica il valore di una variabile o di un campo. Nella tabella seguente vengono illustrati gli operatori di assegnazione X++. Non c'è differenza tra gli operatori di prefisso e suffisso.
| Operatore | Descrizione |
|---|---|
= |
Assegnare l'espressione a destra del segno di uguale alla variabile a sinistra. |
+= |
Assegnare il valore della variabile corrente più l'espressione a destra alla variabile a sinistra. |
++ |
Incrementa la variabile di 1. |
-= |
Assegnare il valore della variabile corrente meno l'espressione a destra alla variabile a sinistra. |
-- |
Decrementare la variabile di 1. |
Esempi di codice per gli operatori di assegnazione
// 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.
}
Operatori aritmetici
Gli operatori aritmetici vengono utilizzati per eseguire calcoli numerici. La maggior parte degli operatori sono binari e accettano due operandi. Tuttavia, l'operatore not (~) è unario e accetta un solo operando. Sintassi per operatori binari: expression1ArithmeticOperatorexpression2 Sintassi per operatori unari : ArithmeticOperatorexpression1
| Operatore | Descrizione |
|---|---|
<< |
L'operatore di spostamento a sinistra esegue lo spostamento a sinistra di expression2 (moltiplicazione per 2) su expression1. |
>> |
L'operatore di spostamento a destra esegue expression2 right shift (divisione per 2) su expression1. |
* |
L'operatore di moltiplicazione moltiplica expression1 per expression2. |
/ |
L'operatore divideexpression1 per expression2. |
DIV |
L'operatore di divisione integer esegue una divisione integer di expression1 per expression2. |
MOD |
L'operatore resto intero restituisce il resto di una divisione intera di expression1 per expression2. |
~ |
L'operatore not , o operatore unario, esegue un'operazione binaria not. |
& |
L'operatore binario AND esegue un'operazione binaria AND su expression1 ed expression2. |
^ |
L'operatore XOR binario esegue un'operazione XOR binaria su expression1 ed expression2. |
| |
L'operatore binario OR esegue un'operazione binaria OR su expression1 ed expression2. |
+ |
L'operatore più aggiunge expression1 a expression2. |
- |
L'operatore meno sottrae expression2 da expression1. |
? |
L'operatore ternario accetta tre espressioni: espressione1 ? espressione2 : espressione3. Se expression1 è true, viene restituito expression2 . In caso contrario, viene restituito expression3 . |
Esempi di codice per operatori aritmetici
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.
Operatori di espressione
Gli as operatori di espressione e is controllano le assegnazioni downcast. Le assegnazioni downcast comportano l'ereditarietà di classi o tabelle. Le istruzioni di assegnazione implicitamente inattive possono causare errori difficili da prevedere e diagnosticare. Puoi usare la as parola chiave per rendere espliciti i tuoi abbattimenti. È possibile utilizzare la is parola chiave per verificare se un downcast è valido in fase di esecuzione.
La parola chiave as
Utilizzare la parola chiave per le assegnazioni che eseguono il as downcast da una variabile di classe base a una variabile di classe derivata. La as parola chiave indica agli altri programmatori e al compilatore che si ritiene che il downcast sarà valido durante la fase di esecuzione.
- Il compilatore segnala un errore per le istruzioni di assegnazione downcast prive della
asparola chiave. - In fase di esecuzione, la parola chiave determina l'assegnazione
asnulldell'istruzione di assegnazione downcast se il downcast non è valido. - Questa
isparola chiave viene spesso utilizzata per verificare in modo sicuro se laasparola chiave funzionerà.
Esempio di codice per la parola chiave as
Nell'esempio di codice seguente la classe DerivedClass estende la classe BaseClass . Nell'esempio di codice sono contenute due assegnazioni valide tra le variabili basec e derivedc . L'assegnazione upcast a basec non richiede la as parola chiave, ma l'assegnazione downcast a derivedc richiede la as parola chiave. Il codice seguente verrà compilato ed eseguito senza errori.
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 parola chiave is
La is parola chiave verifica se un oggetto è un sottotipo di una classe specificata. L'espressione is restituisce true se l'oggetto è un sottotipo della classe o se l'oggetto è dello stesso tipo della classe. Il compilatore segnala un errore se un'espressione is di parole chiave confronta due tipi, ma nessuno dei due tipi è un sottotipo dell'altro e non sono dello stesso tipo. Il compilatore segnala un errore simile per qualsiasi istruzione di assegnazione semplice tra due tipi, in cui nessuno dei due tipi è un sottotipo dell'altro e non sono dello stesso tipo. In fase di esecuzione, il tipo di variabile che fa riferimento all'oggetto sottostante è irrilevante per la is parola chiave. La is parola chiave fa sì che il sistema verifichi l'oggetto a cui fa riferimento la variabile, non il tipo dichiarato della variabile che fa riferimento all'oggetto.
Esempi di codice per la parola chiave is
Negli esempi di codice riportati di seguito vengono illustrate le condizioni che determinano se un'espressione is restituisce true o false. Gli esempi di codice dipendono dal fatto che la classe Form e la classe Query estendono entrambe la 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)));
Esempio di codice per le parole chiave is e as
Nell'esempio di codice riportato di seguito è contenuto un utilizzo tipico della is parola chiave. La as parola chiave viene utilizzata dopo che la is parola chiave ha verificato che la as parola chiave avrà esito positivo. In questo esempio, le is parole chiave e as sono maiuscole per renderle più visibili.
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.
La classe di oggetti come caso speciale
La classe Object può essere visualizzata come un caso speciale nella funzionalità di ereditarietà. Il compilatore ignora il controllo del tipo per le assegnazioni da e verso le variabili dichiarate di tipo Object. Alcune classi ereditano dalla classe Object , alcune classi ereditano da un'altra classe e alcune classi non ereditano da alcuna classe. Sebbene la classe Dialog non erediti da alcuna classe, le istruzioni di assegnazione e chiamata nell'esempio di codice seguente funzionano. Tuttavia, se l'assegnazione è bank4 = dlog3;, avrà esito negativo in fase di compilazione, perché le classi Bank e Dialog non hanno alcuna relazione di ereditarietà tra loro. Il compilatore esegue solo una piccola convalida sulle assegnazioni a una variabile dichiarata appartenente alla classe Object . Il compilatore verifica che l'elemento assegnato alla variabile Object sia un'istanza di una classe. Il compilatore non consente l'assegnazione di un'istanza di un buffer di tabella alla variabile Object . Inoltre, il compilatore non consente l'assegnazione di tipi di dati primitivi, ad esempio int o str, alla variabile 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.");
}
Tabelle
Tutte le tabelle ereditano direttamente dalla tabella di sistema comune, a meno che non ereditino esplicitamente da una tabella diversa. Non è possibile creare un'istanza della tabella Common. Non esiste nel database fisico sottostante. La tabella Common eredita dalla classe xRecord , ma in un modo speciale che non è appropriato per la is parola chiave o la as parola chiave. Quando la as parola chiave viene utilizzata per eseguire un downcast non valido tra le tabelle, la variabile di destinazione fa riferimento a un'entità non Null inutilizzabile. Qualsiasi tentativo di dereferenziare la variabile di destinazione causerà un errore che interrompe il programma.
Le parole chiave è e come e i tipi di dati estesi
Ogni tipo di dati esteso dispone di una proprietà Extends . Lo stile di ereditarietà controllato da questa proprietà è diverso dallo stile di ereditarietà per cui sono progettate le is parole chiave e as .
Operatori relazionali
Nella tabella seguente sono elencati gli operatori relazionali che possono essere utilizzati in X++. La maggior parte degli operatori sono binari e accettano due operandi. Tuttavia, l'operatore not (!) è unario e accetta un solo operando. Sintassi per operatori binari: expression1relationalOperatorexpression2 Sintassi per operatori unari: relationalOperatorexpression1
| Operatore | Descrizione |
|---|---|
like |
L'operatore relazionale like restituisce true se expression1 è like expression2. |
== |
L'operatore relazionale uguale restituisce true se entrambe le espressioni sono uguali. |
>= |
L'operatore relazionale maggiore o uguale a restituisce true se expression1 è maggiore o uguale a expression2. |
<= |
L'operatore relazionale minore o uguale a restituisce true se expression1 è minore o uguale a expression2. |
> |
L'operatore relazionale maggiore di restituisce true se expression1 è maggiore di expression2. |
< |
L'operatore relazionale less than restituisce true se expression1 è minore di expression2. |
!= |
L'operatore relazionale non uguale restituisce true se expression1 è diverso da (ovvero, se non è uguale a) expression2. |
&& |
L'operatore relazionale and restituisce true se sia expression1 che expression2 sono true. |
|| |
L'operatore relazionale or restituisce true se expression1 o expression2 è true o se entrambi sono true. |
! |
L'operatore relazionale not o unario nega l'espressione. Restituisce true se l'espressione è false e false se l'espressione è true. |
L'operatore like
L'operatore like può essere utilizzato * come carattere jolly per zero o più caratteri e ? come carattere jolly per un carattere. La lunghezza massima dell'operando è di 1.000 caratteri. L'operatore like viene valutato dall'SQL sottostante, quindi il risultato potrebbe differire in installazioni diverse. Se le espressioni che si stanno confrontando contengono un percorso di file, è necessario includere quattro barre rovesciate tra ogni elemento, come illustrato nell'esempio seguente.
select * from xRefpaths
where xRefPaths.Path like "\\\\Classes\\\\AddressSelectForm"
L'operatore uguale (==)
Quando si utilizza l'operatore uguale (==) per confrontare gli oggetti, vengono confrontati i riferimenti agli oggetti, non gli oggetti stessi. Questo comportamento potrebbe causare problemi se si confrontano due oggetti, uno dei quali si trova nel server e l'altro nel client. In questi casi, è necessario utilizzare il metodo equal nella classe Object . È possibile eseguire l'override di questo metodo per specificare il significato di parità tra due oggetti. Se non si esegue l'override del metodo uguale , il confronto è identico al confronto eseguito dall'operatore uguale (==).
Esempi di codice per gli operatori relazionali
"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.
Precedenza degli operatori
L'ordine in cui viene valutata un'espressione composta può essere importante. Ad esempio, (x + y / 100) dà un risultato diverso, a seconda che l'addizione o la divisione vengano eseguite per prime. È possibile utilizzare le parentesi (()) per indicare in modo esplicito al compilatore come deve valutare un'espressione. Ad esempio, è possibile specificare (x + y) / 100. Se non si comunica in modo esplicito al compilatore l'ordine in cui si desidera eseguire le operazioni, l'ordine si basa sulla precedenza assegnata agli operatori. Ad esempio, l'operatore di divisione ha una precedenza maggiore rispetto all'operatore di addizione. Pertanto, per l'espressione x + y / 100, il compilatore valuta y / 100 per primo. In altre parole, x + y / 100 è equivalente a x + (y / 100). Per semplificare la lettura e la manutenzione del codice, è necessario essere espliciti. Utilizzare le parentesi per indicare quali operatori devono essere valutati per primi. Nella tabella seguente sono elencati gli operatori in ordine di precedenza. Più alto è l'aspetto di un operatore nella tabella, maggiore è la sua precedenza. Gli operatori con precedenza più alta vengono valutati prima degli operatori con precedenza più bassa. Si noti che la precedenza degli operatori di X++ non è la stessa di altri linguaggi, ad esempio C# e Java.
| Gruppi di operatori, in ordine di precedenza | Operatori |
|---|---|
| Unario | - ~ ! |
| Moltiplicativo, spostamento, AND bit per bit, OR esclusivo bit per bit | * / % DIV << >> & ^ |
| Additivo, inclusivo bit per bit OR | + - | |
| Relazionale, uguaglianza | < <= == != > >= like as is |
| Logico (AND,OR) |
&&
||
|
| Condizionale | ? : |
Gli operatori sulla stessa riga hanno la stessa precedenza. Se un'espressione include più di uno di questi operatori, viene valutata da sinistra a destra, a meno che non vengano usati operatori di assegnazione. Gli operatori di assegnazione vengono valutati da destra a sinistra. Ad esempio, && (logico AND) e || (logico OR) hanno la stessa precedenza e vengono valutati da sinistra a destra. Pertanto:
-
0 && 0 || 1è uguale a1 -
1 || 0 && 0è uguale a0.