Nota
Capaian ke halaman ini memerlukan kebenaran. Anda boleh cuba mendaftar masuk atau menukar direktori.
Capaian ke halaman ini memerlukan kebenaran. Anda boleh cuba menukar direktori.
Nota
Kumpulan minat komuniti kini telah berpindah daripada Yammer kepada Microsoft Viva Engage. Untuk menyertai komuniti Viva Engage dan mengambil bahagian dalam perbincangan terkini, isi borang Minta akses kepada Kewangan dan Operasi Viva Engage Komuniti dan pilih komuniti yang anda mahu sertai.
Artikel ini membandingkan sintaks dan pengaturcaraan X++ dan C#.
Perbandingan X++, C#: Hello World
Bahagian ini membandingkan program X++ yang paling mudah dengan rakan sejawatannya dalam C#.
Perbandingan X++ kepada C#
Bahagian berikut menerangkan beberapa persamaan asas dan perbezaan antara X++ dan C#.
Persamaan
Ciri X++ berikut adalah sama untuk C#:
- Komen baris tunggal (
//) dan berbilang baris (/* */). -
==pengendali (sama) untuk menentukan sama ada dua nilai adalah sama. -
!=(tidak sama dengan) pengendali untuk menentukan sama ada dua nilai tidak setara. -
+(tanda tambah) pengendali untuk penggabungan rentetan.
Perbezaan
Jadual berikut menyenaraikan ciri X++ yang berbeza dalam C#.
| Ciri | X++ | C# | Komen |
|---|---|---|---|
if dan else pernyataan bersyarat |
Pernyataan ini if menerima sebarang jenis ungkapan yang boleh ditukar secara automatik kepada Boolean. Contoh biasa termasuk yang int 0 bermaksud palsu, atau objek yang nol bermaksud palsu. |
Pernyataan itu if memerlukan ungkapan Boolean. |
Struktur sintaks mengenai pendakap kerinting dan kurungan adalah sama antara X++ dan C#. |
| Rentetan literal | Rentetan literal boleh dibatasi menggunakan salah satu kaedah berikut:
|
Rentetan literal mesti dibatasi oleh sepasang tanda petikan berganda ("), aksara. | Untuk X++, aksara tanda petikan berganda biasanya digunakan untuk mengehadkan rentetan. Walau bagaimanapun, adalah mudah untuk mengehadkan rentetan dengan aksara tanda petikan tunggal apabila rentetan anda mesti mengandungi aksara tanda petikan berganda. |
Char type |
Tiada jenis aksara atau char aksara dalam X++. Anda boleh mengisytiharkan a str panjang satu, tetapi ia masih rentetan:str 1 myString = "a"; |
Terdapat dalam char C#. Anda tidak boleh menghantar a char sebagai parameter kepada kaedah yang memasukkan string parameter, walaupun anda boleh menukar secara char eksplisit kepada string. |
Untuk maklumat lanjut tentang jenis data X++, lihat Jenis Data Primitif. |
| Keluaran mesej | X++ menghantar mesej kepada pengguna dalam tetingkap Infolog. Kaedah biasa termasuk:
|
Untuk program baris arahan, mesej boleh dihantar ke konsol. Kaedah biasa termasuk:
|
Sampel X++ dan C#
Bahagian ini mengandungi dua sampel kod mudah. Satu sampel ditulis dalam X++, dan satu lagi dalam C#. Kedua-dua sampel mencapai hasil yang sama. Ciri X++ berikut ditunjukkan:
-
//komen satu baris -
/\*\*/komen berbilang baris -
ifPenyata -
==Pengendali -
!=Pengendali -
+pengendali untuk menggabungkan rentetan - Global::info untuk output mesej, dengan dan tanpa awalan Global::
- Global::ralat untuk output mesej
- Penggunaan aksara petikan tunggal dan berganda (' dan ") sebagai pembatas rentetan.
Nota
Amalan terbaik ialah menggunakan tanda petikan berganda untuk sebarang rentetan yang mungkin dipaparkan kepada pengguna.
Sampel X++
Sampel kod X++ ini dalam bentuk kerja. Terdapat nod bertajuk Pekerjaan dalam Pokok Objek Aplikasi (AOT). Sampel ini boleh ditambah di bawah nod Kerja, dan kemudian kerja boleh dijalankan.
static void JobRs001a_HelloWorld(Args _args)
{
if (1 == 1)
{
// These two info() calls are identical to the X++ compiler.
// The second form is the one typically used in X++.
Global::info("Hello World, 1.");
info('Hello World, 2.');
}
if (1 != 1)
{
error("This message will not appear.");
}
else
{
// These two methods are also from the Global class.
// The + operator concatenates two strings.
warning("This is like info, but is for warnings, 3.");
error("This is like info, but is for errors, 4.");
}
}
Output
Berikut ialah output daripada tetingkap Infolog: Mesej (09:49:48) Hello World, 1. Hello World, 2. Ini seperti maklumat, tetapi untuk amaran, 3. Ini seperti maklumat, tetapi untuk ralat, 4.
Sampel C#
Program C# berikut ialah penulisan semula program X++ sebelumnya.
using System;
class Pgm_CSharp
{
static void Main( string[] args )
{
new Pgm_CSharp().Rs001a_CSharp_HelloWorld();
}
void Rs001a_CSharp_HelloWorld()
{
if (1 == 1)
{
Console .Out .WriteLine("Hello World, Explicit .Out , 1.");
Console .WriteLine("Hello World, Implicit default to .Out , 2.");
}
if (1 != 1)
{
Console .Error .WriteLine("This message will not appear.");
}
else
{
Console .Error .WriteLine(".Error is like .Out, but can be for warnings, 3.");
Console .Error .WriteLine(".Error is like .Out, but is for errors, 4.");
}
}
}
Output
Berikut ialah output sebenar kepada konsol C#:
Hello World, Explicit .Out, 1.
Hello World, Implicit default to .Out, 2.
.Error is like .Out, but can be for warnings, 3.
.Error is like .Out, but is for errors, 4.
Perbandingan X++, C#: Gelung
Bahagian ini membandingkan ciri gelung antara X++ dan C#.
Persamaan
Ciri-ciri berikut adalah sama dalam X++ dan C#:
- Pengisytiharan untuk pembolehubah jenis data primitif int. Pengisytiharan untuk jenis primitif lain hampir sama, tetapi jenisnya mungkin mempunyai nama yang berbeza.
- manakala pernyataan untuk gelung.
- pecahkan pernyataan untuk keluar dari gelung.
- teruskan pernyataan untuk melompat ke bahagian atas gelung.
- <= (kurang daripada atau sama) pengendali perbandingan.
Perbezaan
Jadual berikut menyenaraikan ciri X++ yang berbeza dalam C#.
| Ciri | X++ | C# | Komen |
|---|---|---|---|
Kenyataan itu for . |
Pernyataan for tersedia untuk gelung. | Pernyataan C# for sedikit berbeza daripada for dalam X++. |
Dalam C# anda boleh mengisytiharkan integer kaunter dalam for penyataan. Tetapi dalam X++ kaunter mesti diisytiharkan di luar for penyataan. |
| ++ pengendali peningkatan. | Pengendali kenaikan ++ tersedia dalam X++. Tetapi pembolehubah int yang dihiasi dengan ++ hanya boleh digunakan sebagai pernyataan, bukan sebagai ungkapan. Sebagai contoh, baris kod X++ berikut tidak akan disusun:int age=42;print age++;Walau bagaimanapun, baris kod X++ berikut akan disusun: int age=42;age++; print age; |
Pengendali C# ++ lebih fleksibel daripada dalam X++. | Baris kod berikut adalah sama dalam kedua-dua bahasa:
|
| pengendali modulo. | Dalam X++ pengendali modulo ialah mod. | Dalam C# pengendali modulo ialah %. | Simbol untuk pengendali modulo adalah berbeza, tetapi tingkah laku mereka adalah sama dalam kedua-dua bahasa. |
| Gantung buat sementara waktu program konsol yang telah bermula. | Kenyataan itu pause . |
Dalam C#, program baris arahan boleh dijeda oleh baris kod berikut:Console.In.Read(); |
Dalam X++ anda meneruskan dengan mengklik butang OK pada kotak dialog modal. Dalam C# anda meneruskan dengan menekan mana-mana papan kekunci pada papan kekunci. |
| Paparkan mesej. | Dalam X++, pernyataan memaparkan print mesej dalam tetingkap Cetak. |
Dalam C# mesej boleh dipaparkan pada konsol dengan baris kod berikut:Console.WriteLine(); |
Fungsi X++ print hanya digunakan apabila anda menguji. Program X++ yang menggunakan print hampir selalu menggunakan pernyataan di pause suatu tempat kemudian dalam kod. Untuk kod X++ pengeluaran, gunakan Kaedah Global::info dan bukannya print. Fungsi ini strfmt sering digunakan bersama-sama dengan info. Tiada sebab untuk menggunakan pause selepas info. |
| Buat bunyi. | Fungsi bip mengeluarkan bunyi yang boleh anda dengar. | Dalam C# bunyi yang boleh anda dengar dikeluarkan oleh baris kod berikut:Console.Beep(); |
Kenyataan masing-masing menghasilkan nada pendek. |
Cetak dan Global::info
Sampel kod X++ untuk gelung menggunakan fungsi untuk print memaparkan hasil. Dalam X++ anda boleh menggunakan print pernyataan boleh memaparkan sebarang jenis data primitif tanpa perlu memanggil fungsi yang menukarnya kepada rentetan terlebih dahulu. Ini berguna print dalam situasi ujian pantas. Secara amnya kaedah Global::info digunakan lebih kerap daripada print. Kaedah ini info hanya boleh memaparkan rentetan. Oleh itu fungsi strfmt sering digunakan bersama-sama dengan info. Hadnya print ialah anda tidak boleh menyalin kandungan tetingkap Cetak ke papan keratan (seperti dengan Ctrl+C). Global::info menulis ke tetingkap Infolog yang menyokong salinan ke papan keratan.
Contoh 1: Gelung sementara
Kata kunci while menyokong gelung dalam kedua-dua X++ dan C#.
X++ Contoh semasa
static void JobRs002a_LoopsWhile(Args _args)
{
int nLoops = 1;
while (nLoops <= 88)
{
print nLoops;
pause;
// The X++ modulo operator is mod.
if ((nLoops mod 4) == 0)
{
break;
}
++ nLoops;
}
beep(); // Function.
pause; // X++ keyword.
}
Output
Output dalam tetingkap Cetak X++ adalah seperti berikut:
1
2
3
4
C# Contoh semasa
using System;
public class Pgm_CSharp
{
static void Main( string[] args )
{
new Pgm_CSharp().WhileLoops();
}
void WhileLoops()
{
int nLoops = 1;
while (nLoops <= 88)
{
Console.Out.WriteLine(nLoops.ToString());
Console.Out.WriteLine("(Press any key to resume.)");
// Paused until user presses a key.
Console.In.Read();
if ((nLoops % 4) == 0) {
break;
}
++ nLoops;
}
Console.Beep();
Console.In.Read();
}
}
Output
Output konsol daripada program C# adalah seperti berikut:
1
(Press any key to resume.)
2
(Press any key to resume.)
3
(Press any key to resume.)
4
(Press any key to resume.)
Contoh 2: Gelung for
Kata kunci for menyokong gelung dalam kedua-dua X++ dan C#.
X++ Contoh untuk
Dalam X++ pembolehubah kaunter tidak boleh diisytiharkan sebagai sebahagian daripada pernyataan for .
static void JobRs002a_LoopsWhileFor(Args _args)
{
int ii; // The counter.
for (ii=1; ii < 5; ii++)
{
print ii;
pause;
// You must click the OK button to proceed beyond a pause statement.
// ii is always less than 99.
if (ii < 99)
{
continue;
}
print "This message never appears.";
}
pause;
}
Output
Output dalam tetingkap Cetak X++ adalah seperti berikut:
1
2
3
4
C# Contoh untuk
using System;
public class Pgm_CSharp
{
static void Main( string[] args )
{
new Pgm_CSharp().ForLoops();
}
void ForLoops()
{
int nLoops = 1, ii;
for (ii = 1; ii < 5; ii++)
{
Console.Out.WriteLine(ii.ToString());
Console.Out.WriteLine("(Press any key to resume.)");
Console.In.Read();
if (ii < 99)
{
continue;
}
Console.Out.WriteLine("This message never appears.");
}
Console.Out.WriteLine("(Press any key to resume.)");
Console.In.Read();
}
}
Output
Output konsol daripada program C# adalah seperti berikut:
1
(Press any key to resume.)
2
(Press any key to resume.)
3
(Press any key to resume.)
4
(Press any key to resume.)
(Press any key to resume.)
Perbandingan X++, C#: Suis
Dalam kedua-dua X++ dan C#, pernyataan suis melibatkan kata kunci huruf besar, pecah dan lalai. Jadual berikut menyenaraikan perbezaan dalam pernyataan suis antara X++ dan C#.
| Ciri | X++ | C# | Komen |
|---|---|---|---|
break; pada penghujung setiap blok kes |
Dalam X++, apabila mana-mana blok kes sepadan dengan nilai ungkapan pada klausa suis , semua blok kes dan lalai lain dilaksanakan sehingga break; pernyataan dicapai. Tiada break; pernyataan diperlukan dalam pernyataan suis X++, tetapi break; pernyataan adalah penting dalam hampir semua situasi praktikal. |
Dalam C#, break; pernyataan sentiasa diperlukan selepas pernyataan dalam kes atau blok lalai . Jika klausa kes tidak mempunyai pernyataan antara dirinya dan klausa kes seterusnya, break; pernyataan tidak diperlukan antara kedua-dua klausa kes . |
Kami mengesyorkan agar tidak menghilangkan break; pernyataan selepas sebarang sekatan kes, kerana ia boleh mengelirukan pengaturcara seterusnya yang mengedit kod tersebut. |
break;pada penghujung blok lalai |
Dalam X++ tiada kesan menambah break; pernyataan pada penghujung blok lalai . |
Dalam C# pengkompil memerlukan break; pernyataan pada penghujung blok lalai . |
Untuk maklumat lanjut, lihat Pertukaran Penyata. |
| Hanya nilai malar pada blok kes | Dalam X++ anda boleh menentukan sama ada nilai literal atau pembolehubah pada blok kes. Sebagai contoh, anda boleh menulis kes myInteger:. | Dalam C# anda mesti menentukan tepat satu nilai literal pada setiap blok kes dan tiada pembolehubah dibenarkan. | Tiada komen. |
| Berbilang nilai pada satu blok kes | Dalam X++ anda boleh menentukan berbilang nilai pada setiap blok kes. Nilai mesti dipisahkan dengan koma. Sebagai contoh, anda boleh menulis case 4,5,myInteger:. |
Dalam C# anda mesti menentukan tepat satu nilai pada setiap blok kes. | Dalam X++ adalah lebih baik untuk menulis berbilang nilai pada satu blok kes daripada menghilangkan break; pernyataan pada akhir satu atau lebih blok kes. |
Contoh Kod untuk suis
Bahagian berikut menunjukkan pernyataan suis setanding dalam X++ dan C#.
Contoh suis X++
Contoh suis X++ menunjukkan perkara berikut:
-
case iTemp:dancase (93-90):untuk menunjukkan bahawa ungkapan kes tidak terhad kepada pemalar, seperti dalam C#. -
//break;untuk menunjukkan bahawabreak;pernyataan tidak diperlukan dalam X++, walaupun ia hampir selalu diingini. -
case 2, (93-90), 5:untuk menunjukkan bahawa berbilang ungkapan boleh disenaraikan pada satu klausa kes dalam X++.
static void GXppSwitchJob21(Args _args) // X++ job in AOT > Jobs.
{
int iEnum = 3;
int iTemp = 6;
switch (iEnum)
{
case 1:
case iTemp: // 6
info(strFmt("iEnum is one of these values: 1,6: %1", iEnum));
break;
case 2, (93-90), str2Int("5"): // Equivalent to three 'case' clauses stacked, valid in X++.
//case 2:
//case (93-90): // Value after each 'case' can be a constant, variable, or expression; in X++.
//case str2Int("5"):
info(strFmt("iEnum is one of these values: 2,3,5: %1", iEnum));
//break; // Not required in X++, but usually wanted.
case 4:
info(strFmt("iEnum is one of these values: 4: %1", iEnum));
break;
default:
info(strFmt("iEnum is an unforeseen value: %1", iEnum));
break;
// None of these 'break' occurrences in this example are required for X++ compiler.
}
return;
}
/*** Copied from the Infolog:
Message (02:32:08 pm)
iEnum is one of these values: 2,3,5: 3
iEnum is one of these values: 4: 3
***
Contoh suis C#
Contoh suis C# menunjukkan perkara berikut:
- Kes 1: mempunyai komen yang menjelaskan bahawa hanya ungkapan malar boleh diberikan pada klausa kes.
-
break;pernyataan berlaku selepas pernyataan terakhir dalam setiap blok kes yang mempunyai penyata, seperti yang dikehendaki oleh C#.
using System;
namespace CSharpSwitch2
{
class Program
{
static void Main(string[] args) // C#
{
int iEnum = 3;
switch (iEnum)
{
case 1: // Value after each 'case' must be a constant.
case 6:
Console.WriteLine("iEnum is one of these values: 1,6: " + iEnum.ToString());
break;
//case 2,3,5: // In C# this syntax is invalid, and multiple 'case' clauses are needed.
case 2:
case 3:
case 5:
Console.WriteLine("iEnum is one of these values: 2,3,5: " + iEnum.ToString());
break;
case 4:
Console.WriteLine("iEnum is one of these values: 4: " + iEnum.ToString());
break;
default:
Console.WriteLine("iEnum is an unforeseen value: " + iEnum.ToString());
break;
// All 'break' occurrences in this example are required for C# compiler.
}
return;
}
}
}
/*** Output copied from the console:
>> CSharpSwitch2.exe
iEnum is one of these values: 2,3,5: 3
>>
***/
Perbandingan X++, C#: Kes Rentetan dan Pembatas
Bahagian ini membandingkan rawatan rentetan dengan selongsong campuran dalam X++ dan C#. Ia juga menerangkan pembatas rentetan yang tersedia dalam X++.
Persamaan
Ciri X++ berikut adalah sama seperti dalam C#:
- Garis miring belakang (\) ialah pengendali melarikan diri untuk pembatas rentetan.
- Tanda at (@) membatalkan kesan melarikan diri garis miring belakang apabila tanda at ditulis sejurus sebelum tanda petikan terbuka rentetan.
- Tanda tambah (+) ialah pengendali penggabungan rentetan.
Perbezaan
Ciri X++ yang berbeza dalam C# disenaraikan dalam jadual berikut.
| Ciri | X++ | C# | Komen |
|---|---|---|---|
==pengendali perbandingan |
Tidak sensitif: pengendali == tidak sensitif terhadap perbezaan dalam selongsong rentetan. |
Dalam C#, pengendali == sensitif terhadap perbezaan dalam selongsong rentetan. |
Dalam X++ anda boleh menggunakan Fungsi strCmp untuk perbandingan sensitif huruf besar antara rentetan. |
| Pemisah rentetan | Dalam X++ anda boleh menggunakan sama ada tanda petikan tunggal (') atau berganda (") sebagai pembatas rentetan.Ambil perhatian: Biasanya amalan terbaik ialah menggunakan tanda petikan berganda untuk rentetan yang mungkin dipaparkan kepada pengguna. Walau bagaimanapun, adalah mudah untuk mengehadkan rentetan dengan tanda petikan tunggal apabila tanda petikan berganda ialah salah satu aksara dalam rentetan. |
Dalam C# anda mesti menggunakan tanda petikan berganda sebagai pembatas rentetan. Ini merujuk kepada jenis System.String. |
Dalam X++ dan C# anda mempunyai pilihan untuk membenamkan pembatas dalam rentetan literal dan melarikan diri dengannya dengan . Dalam X++ anda juga mempunyai alternatif untuk membenamkan tanda petikan tunggal dalam rentetan yang dibatasi oleh tanda petikan berganda (atau sebaliknya), tanpa perlu menggunakan melarikan diri. |
| Pembatas aksara | X++ mempunyai jenis data rentetan (str), tetapi tiada jenis aksara. |
Dalam C# anda mesti menggunakan tanda petikan tunggal sebagai pembatas aksara. Ini merujuk kepada jenis System.Char. |
Dalam Rangka Kerja .NET, System.String panjang satu ialah jenis data yang berbeza daripada System.Char aksara. |
Contoh 1: Kepekaan Kes Pengendali ==
Pengendali == dan != tidak sensitif huruf besar dalam X++, tetapi sensitif huruf besar dalam C#, seperti yang digambarkan oleh contoh berikut.
| X++ | C# | Komen |
|---|---|---|
"HELLO" == "hello" Benar dalam X++. |
"HELLO" == "hello" Palsu dalam C#. |
Perbandingan kes yang berbeza antara X++ dan C#. |
Contoh 2: Pengendali Penggabungan Rentetan +
Pengendali + dan += digunakan untuk menggabungkan rentetan dalam kedua-dua X++ dan C#, seperti yang ditunjukkan oleh contoh dalam jadual berikut.
| X++ | C# | Komen |
|---|---|---|
myString1 = "Hello" + " world"; Hasilnya ialah kesaksamaan: myString1 == "Hello world" |
(Sama seperti untuk X++.) | Dalam kedua-dua X++ dan C#, tingkah laku pengendali + bergantung pada jenis data operandnya. Pengendali menggabungkan rentetan, atau menambah nombor. |
mystring2 = "Hello"; myString2 += " world"; Hasilnya ialah kesaksamaan: myString2 == "Hello world" |
(Sama seperti untuk X++.) | Dalam kedua-dua X++ dan C#, pernyataan berikut adalah setara: a = a + b; a += b; |
Contoh 3: Membenamkan dan Melarikan Diri Pembatas Rentetan
Sama ada tanda petikan tunggal atau berganda boleh digunakan untuk mengehadkan rentetan dalam X++. Aksara melarikan diri (\) boleh digunakan untuk membenamkan pembatas dalam rentetan. Ini digambarkan dalam jadual berikut.
| X++ | C# | Komen |
|---|---|---|
myString1 = "They said \"yes\"."; Keputusan: They said "yes". |
(Sama seperti untuk X++.) | Watak melarikan diri membolehkan anda membenamkan pembatas rentetan di dalam rentetan. |
myString2 = 'They said "yes".'; Keputusan: They said "yes". |
Sintaks C# tidak membenarkan tanda petikan tunggal untuk mengehadkan rentetan. | Untuk rentetan yang mungkin dilihat oleh pengguna, ia dianggap sebagai amalan terbaik untuk menggunakan aksara melarikan diri dan bukannya tanda petikan tunggal seperti yang ditunjukkan dalam contoh. |
myString3 = "They said 'yes'."; Keputusan: They said 'yes'. |
(Sama seperti untuk X++.) | Dalam X++, tanda petikan tunggal tidak dianggap sebagai pembatas melainkan rentetan bermula dengan pembatas tanda petikan tunggal. Dalam C# tanda petikan tunggal tidak mempunyai makna istimewa untuk rentetan, dan ia tidak boleh digunakan untuk mengehadkan rentetan. Dalam C# tanda petikan tunggal ialah pembatas yang diperlukan untuk literal jenis System.Char. X++ tidak mempunyai jenis data aksara. |
str myString4 = 'C'; Di sini petikan tunggal ialah pembatas rentetan. |
char myChar4 = 'C'; Di sini tanda petikan tunggal ialah System.Char pembatas, bukan System.String pembatas. |
X++ tidak mempunyai jenis data yang sepadan dengan System.Char dalam Rangka Kerja .NET. Rentetan X++ yang terhad kepada panjang satu masih rentetan, bukan jenis data aksara. |
Contoh 4: Watak Melarikan Diri Tunggal
Contoh yang menggambarkan aksara melarikan diri tunggal sama ada dalam input atau output ditunjukkan dalam jadual berikut.
| X++ | C# | Komen |
|---|---|---|
myString1 = "Red\ shoe"; Keputusan: Red shoe |
Rentetan literal dalam C# tidak boleh mengandungi dua jujukan aksara melarikan diri diikuti dengan ruang, seperti "\ ". Ralat pengkompil berlaku. | Apabila pengkompil X++ menemui jujukan dua aksara "\ ", ia membuang aksara melarikan diri tunggal. |
myString2 = "Red\\ shoe"; Keputusan: Red\ shoe |
(Sama seperti untuk X++.) | Dalam sepasang watak melarikan diri, yang pertama menafikan makna istimewa yang kedua. |
Perbandingan: Sintaks Tatasusunan
Terdapat persamaan dan perbezaan dalam ciri dan sintaks untuk tatasusunan dalam X++ berbanding C#.
Persamaan
Secara keseluruhan terdapat banyak persamaan dalam sintaks dan rawatan tatasusunan dalam X++ dan C#. Walau bagaimanapun, terdapat banyak perbezaan.
Perbezaan
Jadual berikut menyenaraikan kawasan dalam sintaks [] untuk tatasusunan yang berbeza untuk X++ dan C#.
| Kategori | X++ | C# | Komen |
|---|---|---|---|
| Pengisytiharan | Tatasusunan diisytiharkan dengan kurungan segi empat sama ditambahkan pada nama pembolehubah. | Tatasusunan diisytiharkan dengan kurungan segi empat sama ditambahkan pada jenis data. | int myInts[]; // X++ Ambil perhatian: Tatasusunan X++ tidak boleh menjadi parameter dalam kaedah.
|
| Pengisytiharan | Sintaks tatasusunan hanya menyokong jenis data primitif, seperti int dan str. Sintaks tidak menyokong kelas atau jadual. |
Sintaks tatasusunan menyokong jenis dan kelas data primitif. | Dalam X++ anda boleh menggunakan Array Tatasusunan untuk tatasusunan objek. |
| Pengisytiharan | X++ terhad kepada tatasusunan dimensi tunggal (myStrings[8]). | C# menambah sokongan untuk tatasusunan berbilang dimensi (myStrings[8,3]) dan untuk tatasusunan bergerigi (myStrings[8][3]). | Dalam X++ anda tidak boleh mempunyai pelbagai tatasusunan. Walau bagaimanapun, terdapat sintaks lanjutan untuk mengehadkan jumlah memori aktif yang boleh digunakan oleh tatasusunan besar, yang kelihatan seperti sintaks berbilang dimensi dalam C#: int intArray[1024,16];. Untuk maklumat lanjut, lihat Pengoptimuman Prestasi Amalan Terbaik: Menukar Tatasusunan ke Cakera. |
| Pengisytiharan | Dalam X++ tatasusunan ialah binaan khas tetapi ia bukan objek. | Dalam C# semua tatasusunan ialah objek tanpa mengira variasi sintaks. | X++ memang mempunyai kelas Array, tetapi mekanisme asasnya berbeza daripada tatasusunan yang dicipta dengan menggunakan sintaks []. Dalam C# semua tatasusunan menggunakan mekanisme asas yang sama, tanpa mengira sama ada sintaks System.Array [] kelas digunakan dalam kod anda. |
| Panjang | Dalam X++ panjang tatasusunan bersaiz statik ditentukan dalam sintaks pengisytiharan. | Dalam C# saiz tatasusunan ditentukan apabila objek tatasusunan dibina. | Apabila anda menggunakan sintaks pengisytiharan [] dalam X++, tiada lagi persediaan diperlukan sebelum anda menetapkan nilai kepada tatasusunan. Dalam C# anda mesti mengisytiharkan dan kemudian membina tatasusunan sebelum memperuntukkan kepadanya. |
| Panjang | Tatasusunan X++ boleh mempunyai panjang dinamik yang boleh ditingkatkan walaupun selepas populasi telah bermula. Ini hanya terpakai apabila tatasusunan diisytiharkan tanpa nombor di dalam []. Prestasi mungkin diperlahankan jika panjang tatasusunan dinamik meningkat berkali-kali. | Dalam C# panjang tatasusunan tidak boleh diubah selepas panjang ditetapkan. | Dalam serpihan kod X++ berikut, hanya myInts tatasusunan yang dinamik dan boleh meningkat dalam saiz. int myInts[]; int myBools[5]; myInts[2] = 12; myInts[3] = 13; myBools[6] = 26; //Error |
| Panjang | Anda boleh mendapatkan panjang beberapa tatasusunan dengan menggunakan dimOf fungsi. |
Tatasusunan C# ialah objek yang mempunyai Length sifat. |
Tiada komen. |
| Pengindeksan | Pengindeksan tatasusunan adalah berasaskan 1. | Pengindeksan tatasusunan adalah berasaskan 0. | mtIntArray[0] akan menyebabkan ralat dalam X++. |
| Pemalar | Dalam X++ nilai malar paling baik dicapai dengan menggunakan arahan prapengkompil #define . | Dalam C# anda boleh menghiasi pengisytiharan pembolehubah anda dengan kata kunci const, untuk mencapai nilai malar. | X++ tidak mempunyai kata kunci const . C# tidak boleh memperuntukkan nilai kepada pembolehubah yang dicipta oleh arahan prapengkompilasi #define. |
Sampel X++ dan C#
Sampel kod berikut menunjukkan cara tatasusunan jenis data primitif dikendalikan. Sampel pertama adalah dalam X++, dan sampel kedua adalah dalam C#. Kedua-dua sampel mencapai hasil yang sama.
Sampel X++
static void JobRs005a_ArraySimple(Args _args)
{
#define.macroArrayLength(3)
// Static length.
str sSports[#macroArrayLength];
// Dynamic length, changeable during run time.
int years[];
int xx;
Global::warning("-------- SPORTS --------");
sSports[#macroArrayLength] = "Baseball";
for (xx=1; xx <= #macroArrayLength; xx++)
{
info(int2str(xx) + " , [" + sSports[xx] + "]");
}
warning("-------- YEARS --------");
years[ 4] = 2008;
years[10] = 1930;
for (xx=1; xx <= 10; xx++)
{
info(int2str(xx) + " , " + int2str(years[xx]));
}
}
Output
Output kepada Infolog adalah seperti berikut:
Message (14:16:08)
-------- SPORTS --------
1 , []
2 , []
3 , [Baseball]
-------- YEARS --------
1 , 0
2 , 0
3 , 0
4 , 2008
5 , 0
6 , 0
7 , 0
8 , 0
9 , 0
10 , 1930
Sampel C#
using System;
public class Pgm_CSharp
{
static public void Main( string[] args )
{
new Pgm_CSharp().ArraySimple();
}
private void ArraySimple()
{
const int const_iMacroArrayLength = 3;
// In C# the length is set at construction during run.
string[] sSports;
int[] years;
int xx;
Console.WriteLine("-------- SPORTS --------");
sSports = new string[const_iMacroArrayLength];
sSports[const_iMacroArrayLength - 1] = "Baseball";
for (xx=0; xx < const_iMacroArrayLength; xx++)
{
Console.WriteLine(xx.ToString() + " , [" + sSports[xx] + "]");
}
Console.WriteLine("-------- YEARS --------");
// In C# you must construct the array before assigning to it.
years = new int[10];
years[ 4] = 2008;
years[10 - 1] = 1930;
for (xx=0; xx < 10; xx++)
{
Console.WriteLine(xx.ToString() + " , [" + years[xx].ToString() + "]");
}
}
} // EOClass
Output
Output daripada program C# ke konsol baris arahan adalah seperti berikut:
-------- SPORTS --------
0 , []
1 , []
2 , [Baseball]
-------- YEARS --------
0 , [0]
1 , [0]
2 , [0]
3 , [0]
4 , [2008]
5 , [0]
6 , [0]
7 , [0]
8 , [0]
9 , [1930]
Ciri X++ seperti tatasusunan tambahan
Bekas ialah jenis data khas yang tersedia dalam X++. Ia boleh dianggap serupa dengan tatasusunan, atau serupa dengan List koleksi.
Perbandingan: Koleksi
Dalam aplikasi kewangan dan operasi, anda boleh menggunakan kelas koleksi X++ List . Rangka Kerja .NET yang digunakan dalam C# mempunyai kelas serupa bernama System.Collections.Generic.List.
Membandingkan Penggunaan Kelas Senarai
Jadual berikut membandingkan kaedah pada kelas X++ List dengan kaedah pada System.Collections.Generic.List daripada .NET Framework dan C#.
| Ciri | X++ | C# | Komen |
|---|---|---|---|
| Pengisytiharan kutipan | List myList; |
List<string> myList; |
Pengisytiharan X++ tidak termasuk jenis elemen yang akan disimpan. |
| Pengisytiharan iterator | ListIterator iterListEnumerator enumer; |
Iter rentetan< IEnumerator>; | Dalam X++ ListIterator objek mempunyai kaedah yang boleh insert dan delete item daripada .List X++ ListEnumerator tidak boleh mengubah suai kandungan List. Dalam X++ ListEnumerator objek sentiasa dicipta pada peringkat yang sama dengan List. Ini tidak selalu benar untuk ListIterator. |
| Mendapatkan iterator | new ListIterator (myList)myList.getEnumerator() |
myList.GetEnumerator() |
Dalam kedua-dua X++ dan C#, objek Senarai mempunyai kaedah pengambil untuk penghitung yang berkaitan. |
| Pembina | new List(Types::String) |
new List<string>() |
Maklumat tentang jenis objek yang akan disimpan di dalam List kelas diberikan kepada pembina dalam kedua-dua X++ dan C#. |
| Mengemas kini data | Penghitung – penghitung menjadi tidak sah jika mana-mana item dalam ditambah List atau dialih keluar.Iterator – lelang mempunyai kaedah yang memasukkan dan memadam item daripada . List Iterator kekal sah. |
Penghitung – penghitung menjadi tidak sah jika mana-mana item dalam ditambah List atau dialih keluar. |
Penghitung menjadi tidak sah selepas item ditambah atau dipadamkan daripada , dalam kedua-dua ListX++ dan C#. |
| Mengemas kini data | Dalam X++ List kelas mempunyai kaedah untuk menambah item pada permulaan atau akhir senarai. |
Dalam C# List kelas mempunyai kaedah untuk menambah ahli pada mana-mana kedudukan dalam senarai. Ia juga mempunyai kaedah untuk mengeluarkan item dari mana-mana kedudukan. |
Dalam item X++ boleh dialih keluar daripada satu-satunya List oleh iterator. |
Contoh 1: Pengisytiharan Senarai
Contoh kod berikut ialah dalam X++ dan C# yang mengisytiharkan List koleksi.
// X++
List listStrings ,list2 ,listMerged;
ListIterator literator;
// C#
using System;
using System.Collections.Generic;
List<string> listStrings ,list2 ,listMerged; IEnumerator<string> literator;
Contoh 2: Pembinaan Senarai
Dalam kedua-dua bahasa, jenis item yang disimpan oleh koleksi mesti dinyatakan pada masa pembinaan. Untuk jenis kelas, X++ tidak boleh menjadi lebih spesifik daripada sama ada jenis itu ialah kelas (Jenis::Kelas). Contoh kod berikut ialah dalam X++ dan C#.
// X++
listStrings = new List( Types::String );
// C#
listStrings = new List<string>;
Contoh 3: Tambah Item pada Senarai
Dalam kedua-dua X++ dan C#, koleksi menyediakan kaedah untuk menambah item pada penghujung koleksi dan untuk memasukkan item sebagai permulaan. Dalam C# koleksi menyediakan kaedah untuk memasukkan pada bila-bila masa dalam koleksi berdasarkan nilai indeks. Dalam X++, lelang koleksi boleh memasukkan item pada kedudukan semasanya. Contoh kod berikut ialah dalam X++ dan C#.
// X++
listStrings.addEnd ("StringBB.");
listStrings.addStart ("StringAA.");
// Iterator performs a midpoint insert at current position.
listIterator.insert ("dog");
// C#
listStrings.Add ("StringBB.");
listStrings.Insert (0 ,"StringAA.");
// Index 7 determines the insertion point.
listStrings.Insert (7 ,"dog");
Contoh 4: Lelaran Melalui Senarai
Kedua-dua X++ dan C# mempunyai kelas iterator yang boleh anda gunakan untuk melangkah melalui item dalam koleksi seperti yang ditunjukkan dalam contoh berikut.
// X++
literator = new ListIterator (listStrings);
// Now the iterator points at the first item.
// The more method answers whether
// the iterator currently points
// at an item.
while (literator.more())
{
info(any2str (literator.value()));
literator.next();
}
// C#
literator = listStrings .GetEnumerator();
// Now enumerator points before the first item, not at the first item.
// The MoveNext method both advances the item pointer, and
// answers whether the pointer is pointing at an item.
while (literator.MoveNext())
{
Console.WriteLine (literator.Current);
}
Contoh 4b: foreach dalam C#
Dalam C# kata kunci foreach sering digunakan untuk memudahkan tugas mengulangi melalui senarai. Contoh kod berikut berkelakuan sama seperti contoh C# sebelumnya.
foreach (string currentString in listStrings)
{
Console.WriteLine(currentString);
}
Contoh 5: Padamkan Item Kedua
Contoh kod berikut memadamkan item kedua daripada koleksi. Dalam X++ ini memerlukan iterator. Dalam C# koleksi itu sendiri menyediakan kaedah untuk mengalih keluar item.
// X++
literator.begin();
literator.next();
literator.delete();
// C#
listStrings.RemoveAt(1);
Contoh 6: Gabungkan Dua Koleksi
Contoh kod berikut menggabungkan kandungan dua koleksi menjadi satu.
// X++
listStrings = List::merge(listStrings ,listStr3);
// Or use the .appendList method:
listStrings.appendList (listStr3);
// C#
listStrings.InsertRange(listStrings.Count ,listStr3);
Perbandingan: Koleksi kunci dengan nilai
Dalam aplikasi kewangan dan operasi, anda boleh menggunakan Map kelas koleksi. Koleksi ini Map memegang pasangan nilai, nilai utama ditambah nilai data. Ini menyerupai kelas .NET Framework bernama System.Collections.Generic.Dictionary.
Persamaan
Senarai berikut menerangkan persamaan antara X++ dan C# berkenaan koleksi mereka yang menyimpan pasangan nilai kunci:
- Kedua-duanya menghalang kunci pendua.
- Kedua-duanya menggunakan penghitung (atau iterator) untuk menggelung item.
- Kedua-dua objek pengumpulan nilai kunci dibina dengan sebutan jenis yang disimpan sebagai kunci dan nilai.
- Kedua-duanya boleh menyimpan objek kelas, dan tidak terhad kepada menyimpan primitif seperti int.
Perbezaan
Jadual berikut menerangkan perbezaan antara X++ dan C# berkenaan kelas koleksi mereka yang menyimpan pasangan nilai kunci:
| Ciri | X++ | C# | Komen |
|---|---|---|---|
| Kekunci pendua | Dalam X++ Map kelas menghalang kunci pendua dengan secara tersirat merawat panggilan anda kepada kaedahnya insert sebagai operasi untuk mengemas kini hanya nilai yang dikaitkan dengan kunci. |
Dalam C# Dictionary kelas melemparkan pengecualian apabila anda cuba menambah kunci pendua. |
Kekunci pendua dihalang dalam kedua-dua bahasa, walaupun dengan teknik yang berbeza. |
| Padamkan item | Dalam X++ delete kaedah pada objek iterator digunakan untuk mengalih keluar pasangan nilai kunci yang tidak diingini daripada .Map |
Dalam C# Dictionary kelas mempunyai remove kaedah. |
Dalam kedua-dua bahasa, penghitung dijadikan tidak sah jika kiraan item koleksi diubah suai semasa hayat penghitung. |
Contoh 1: Pengisytiharan Kutipan Key-Value
Dalam kedua-dua bahasa, jenis item yang disimpan oleh koleksi nilai kunci mesti ditentukan. Dalam X++ jenis ditentukan pada masa pembinaan. Dalam C# jenis ditentukan pada kedua-dua masa pengisytiharan dan masa pembinaan. Contoh kod berikut ialah dalam X++ dan C#.
// X++
Map mapKeyValue;
MapEnumerator enumer;
MapIterator mapIter;
// C#
Dictionary<int,string> dictKeyValue;
IEnumerator<SysCollGen.KeyValuePair<int,string>> enumer;
KeyValuePair<int,string> kvpCurrentKeyValuePair;
Contoh 2: Pembinaan Koleksi
Dalam kedua-dua bahasa, jenis item yang disimpan oleh koleksi nilai kunci yang ditentukan semasa pembinaan. Untuk jenis kelas, X++ tidak boleh menjadi lebih spesifik daripada sama ada jenis itu ialah kelas (Jenis::Kelas). Contoh kod berikut ialah dalam X++ dan C#.
// X++
mapKeyValue = new Map(Types::Integer, Types::String);
// C#
dictKeyValue = new Dictionary<int,string>();
Contoh 3: Tambah item pada koleksi
Hampir tiada perbezaan dalam cara item ditambah pada koleksi nilai kunci dalam X++ dan C# seperti yang ditunjukkan dalam contoh kod berikut.
// X++
mapKeyValue.insert(xx ,int2str(xx) + “_Value”);
// C#
dictKeyValue.Add(xx ,xx.ToString() + “_Value”);
Contoh 4: Lelaran Melalui Koleksi Key-Value
Penghitung digunakan untuk menggelung koleksi nilai kunci dalam kedua-dua X++ dan C# seperti yang ditunjukkan dalam contoh kod berikut.
// X++
enumer = mapKeyValue.getEnumerator();
while (enumer.moveNext())
{
iCurrentKey = enumer.currentKey();
sCurrentValue = enumer.currentValue();
// Display key and value here.
}
// C#
enumer = dictKeyValue.GetEnumerator();
while (enumer.MoveNext())
{
kvpCurrentKeyValuePair = enumer.Current;
// Display .Key and .Value properties=
// of kvpCurrentKeyValuePair here.
}
Contoh 5: Kemas kini Nilai yang Dikaitkan dengan Kunci
Sintaks sangat berbeza antara kedua-dua bahasa untuk kemas kini nilai yang dikaitkan dengan kunci tertentu. Contoh kod ollowing adalah untuk kunci 102.
// X++
mapKeyValue.insert(
102 ,
”.insert(), Re-inserted” + ” key 102 with a different value.”);
// C#
dictKeyValue[102] =
“The semi-hidden .item property in C#, Updated the value for key 102.”;
Contoh 6: Padamkan Satu Item
Sintaks sangat berbeza antara kedua-dua bahasa untuk memadamkan satu pasangan nilai kunci daripada koleksi, sambil mengulangi melalui ahli koleksi. Contoh kod untuk kunci 102 ditunjukkan di bawah.
// X++
mapIter = new MapIterator(mapKeyValue);
//mapIter.begin();
while (mapIter.more())
{
iCurrentKey = mapIter.key();
if (104 == iCurrentKey)
{
// mapKeyValue.remove would invalidate the iterator.
mapIter.delete();
break;
}
mapIter.next();
}
// C#
dictKeyValue.Remove(104);
Perbandingan: Pengecualian
Terdapat beberapa persamaan tetapi banyak perbezaan apabila kita membandingkan tingkah laku berkaitan pengecualian antara X++ dan C#. Kata kunci cuba, tangkap dan buang berkelakuan sama dalam X++ dan C#. Tetapi jenis pengecualian yang dilemparkan dan ditangkap adalah berbeza untuk kedua-dua bahasa.
Persamaan
Persamaan antara X++ dan C# mengenai ciri pengecualian mereka termasuk contoh berikut:
- Kedua-dua bahasa mempunyai kata kunci cuba yang sama.
- Kedua-duanya mempunyai kata kunci tangkapan yang sama.
- Kedua-duanya mendayakan pernyataan tangkapan yang tidak menentukan sebarang pengecualian tertentu. Pernyataan tangkapan sedemikian menangkap semua pengecualian yang mencapainya.
- Kedua-duanya mempunyai kata kunci lontaran yang sama.
Perbezaan
Perbezaan berkaitan pengecualian antara X++ dan C# diterangkan dalam jadual berikut.
| Ciri | X++ | C# | Komen |
|---|---|---|---|
| Mencuba | Melompat ke arahan pertama dalam blok percubaan yang berkaitan. Untuk maklumat lanjut, lihat Pengendalian Pengecualian dengan cuba dan tangkap Kata kunci. | Kefungsian kata kunci percubaan semula boleh ditiru dalam kod C#, tetapi tiada kata kunci yang sepadan. | Hanya X++ mempunyai kata kunci percubaan semula . C# tidak mempunyai rakan sejawatan. Untuk maklumat lanjut, lihat Perbandingan X++, C#: Percubaan Semula Automatik Selepas Pengecualian. |
| Akhirnya | Kata finally kunci disokong untuk mengikuti try kata kunci dan catch . |
Kata kunci akhirnya menandakan blok kod yang mengikuti blok cuba dan tangkap . Akhirnya akan dilaksanakan tanpa mengira sama ada sebarang pengecualian dilemparkan atau ditangkap. | Semantik adalah sama dengan semantik dalam C#. |
| Pengecualian khusus | Dalam X++ pengecualian ialah elemen Exception enum, seperti Ralat, Kebuntuan atau CodeAccessSecurity. Tiada pengecualian boleh mengandungi yang lain. |
Dalam C# pengecualian ialah tika System.Exception kelas asas, atau mana-mana kelas yang mewarisi daripadanya. Pengecualian boleh terkandung dalam InnerException sifat pengecualian yang dilemparkan. |
Dalam X++ setiap pengecualian yang dilemparkan ialah nilai enum Pengecualian. Untuk maklumat lanjut, lihat Penghitungan Pengecualian. |
| Mesej pengecualian | Dalam X++ mesej yang dicipta apabila pengecualian dibangkitkan hanya tersedia dalam Log Maklumat dan mesej tidak terikat secara langsung kepada pengecualian. | Dalam C# mesej ialah Message ahli System.Exception objek. |
Dalam X++ kaedah Global::error ialah mekanisme yang memaparkan mesej pengecualian dalam Infolog. Untuk maklumat lanjut, lihat Pengendalian Pengecualian dengan cuba dan tangkap Kata kunci. |
| Syarat pengecualian | Dalam X++ ralat berlaku apabila anda memanggil kaedah contoh pada pembolehubah objek yang belum mempunyai apa-apa yang diberikan kepadanya. Walau bagaimanapun, tiada pengecualian dikemukakan bersama-sama dengan ralat ini. Oleh itu, tiada catch blok boleh mendapat kawalan walaupun pembolehubah yang tidak ditugaskan disalahgunakan dalam try blok. Dalam contoh kod berikut, ralat yang disebabkan oleh kod box4.toString(); tidak menyebabkan kawalan dipindahkan ke mana-mana catch blok: DialogBox box4;try { box4.toString();info("toString did not error, but expected an error."); } catch (Pengecualian::Error) // Tiada nilai Pengecualian menangkap ini. { info("Invalid use of box4 gave control to catch, unexpected."); } |
Dalam C# a System.NullReferenceException dinaikkan apabila pembolehubah yang tidak dimulakan dianggap sebagai rujukan objek. |
Mungkin terdapat beberapa perbezaan lain dalam keadaan yang menimbulkan pengecualian. |
| Urus niaga SQL | Dalam X++ apabila pengecualian SQL berlaku dalam transaksi ttsBegin - ttsCommit , tiada pernyataan tangkapan di dalam blok transaksi boleh memproses pengecualian. | Dalam C# blok tangkapan dalam transaksi SQL boleh menangkap pengecualian. |
Contoh
Ciri X++ berikut ditunjukkan:
- cuba kata kunci.
- tangkap kata kunci.
- Tingkah laku selepas pengecualian Pengecualian::Ralat berlaku.
Contoh X++
// X++
static void JobRs008a_Exceptions(Args _args)
{
str sStrings[4];
int iIndex = 77;
try
{
info("On purpose, this uses an invalid index for this array: " + sStrings[iIndex]);
warning("This message doesn't appear in the Infolog," + " it's unreached code.");
}
// Next is a catch for some of the values of
// the X++ Exception enumeration.
catch (Exception::CodeAccessSecurity)
{
info("In catch block for -- Exception::CodeAccessSecurity");
}
catch (Exception::Error)
{
info("In catch block for -- Exception::Error");
}
catch (Exception::Warning)
{
info("In catch block for -- Exception::Warning");
}
catch
{
info("This last 'catch' is of an unspecified exception.");
}
//finally
//{
// //Global::Warning("'finally' is not an X++ keyword, although it's in C#.");
//}
info("End of program.");
}
Output
Berikut ialah output daripada tetingkap Infolog:
Message (18:07:24)
Error executing code: Array index 77 is out of bounds.
Stack trace
(C)\Jobs\JobRs008a_Exceptions - line 8
In catch block for -- Exception::Error
End of program.
Sampel C#
Program C# berikut ialah penulisan semula program X++ sebelumnya.
// C#
using System;
public class Pgm_CSharp
{
static void Main( string[] args )
{
new Pgm_CSharp().Rs008a_CSharp_Exceptions();
}
void Rs008a_CSharp_Exceptions()
{
//str sStrings[4];
string[] sStrings = new string[4];
try
{
Console.WriteLine("On purpose, this uses an invalid index for this array: " + sStrings[77]);
Console.Error.WriteLine("This message doesn't appear in the Infolog, it's unreached code.");
}
catch (NullReferenceException exc)
{
Console.WriteLine("(e1) In catch block for -- " + exc.GetType().ToString() );
}
catch (IndexOutOfRangeException exc)
{
Console.WriteLine("(e2) In catch block for -- " + exc.GetType().ToString() );
}
// In C#, System.Exception is the base of all
// .NET Framework exception classes.
// No as yet uncaught exception can get beyond
// this next catch.
catch (Exception exc)
{
Console.WriteLine("This last 'catch' is of the abstract base type Exception: "
+ exc.GetType().ToString());
}
// The preceding catch of System.Exception makes this catch of
// an unspecified exception redundant and unnecessary.
//catch
//{
// Console.WriteLine("This last 'catch' is"
// + " of an unspecified exception.");
//}
finally
{
Console.WriteLine("'finally' is not an X++ keyword, although it's in C#.");
}
Console.WriteLine("End of program.");
}
} // EOClass
Output
Berikut ialah output kepada konsol C#:
(e2) In catch block for -- System.IndexOutOfRangeException
'finally' is not an X++ keyword, although it's in C#.
End of program.
Perbandingan: Percubaan semula automatik selepas pengecualian
Kadangkala anda boleh menulis kod dalam blok tangkapan yang membetulkan punca pengecualian yang berlaku semasa masa jalan. X++ menyediakan kata kunci percubaan semula yang boleh digunakan hanya di dalam blok tangkapan . Kata kunci percubaan semula membolehkan program melompat kembali ke permulaan blok percubaan selepas masalah telah diperbetulkan oleh kod dalam blok tangkapan . C# tidak mempunyai kata kunci percubaan semula . Walau bagaimanapun, kod C# boleh ditulis untuk memberikan tingkah laku yang setara.
Sampel Kod untuk Percubaan Semula
Program sampel X++ berikut menyebabkan Pengecualian::Ralat dibangkitkan. Ini berlaku apabila ia mula-mula cuba membaca elemen daripada sStrings tatasusunan dengan menggunakan nilai indeks tidak sah. Apabila pengecualian ditangkap, tindakan pembetulan diambil semasa masa larian di dalam blok tangkapan . Pernyataan percubaan semula kemudian melompat kembali ke pernyataan pertama dalam blok cubaan . Lelaran kedua ini berfungsi tanpa menemui sebarang pengecualian.
static void JobRs008b_ExceptionsAndRetry(Args _args)
{
str sStrings[4];
str sTemp;
int iIndex = 0;
sStrings[1] = "First array element.";
try
{
print("At top of try block: " + int2str(iIndex));
sTemp = sStrings[iIndex];
print( "The array element is: " + sTemp );
}
catch (Exception::Error)
{
print("In catch of -- Exception::Error (will retry)." + " Entering catch.");
++iIndex;
print("In catch of -- Exception::Error (will retry)." + " Leaving catch.");
// Here is the retry statement.
retry;
}
print("End of X++ retry program.");
pause;
}
Output
Berikut ialah output kepada tetingkap Cetak:
At top of try block: 0
In catch of -- Exception::Error (will retry). Entering catch.
In catch of -- Exception::Error (will retry). Leaving catch.
At top of try block: 1
The array element is: First array element.
End of X++ retry program.
Sampel C#
Sampel C# berikut bukanlah terjemahan baris demi baris daripada sampel X++ sebelumnya. Sebaliknya program C# mempunyai struktur yang berbeza supaya ia meniru tingkah laku kata kunci percubaan semula yang bergantung kepada program X++. Blok cuba dan tangkap adalah dalam kaedah yang dipanggil. Pembolehubah yang digunakan dalam blok cuba disimpan dalam kaedah pemanggil. Kaedah pemanggil menghantar pembolehubah sebagai parameter yang dihiasi dengan kata kunci ref , supaya nilainya boleh diperbetulkan di dalam blok tangkapan kaedah yang dipanggil. Kaedah yang dipanggil menangkap semua pengecualian dan mengembalikan boolean untuk berkomunikasi kembali kepada pemanggil sama ada panggilan kedua diperlukan.
// C#
using System;
public class Pgm_CSharp
{
static void Main(string[] args)
{
new Pgm_CSharp() .Rs008b_CSharp_ExceptionsAndRetry();
}
void Rs008b_CSharp_ExceptionsAndRetry() // Caller
{
int iIndex = -1
, iNumRetriesAllowed = 3;
bool bReturnCode = true; // Means call the callee method.
for (int xx=0; xx <= iNumRetriesAllowed; xx++)
{
if (bReturnCode)
{
bReturnCode = this.Rs008b_CSharp_ExceptionsAndRetry_Callee(ref iIndex);
}
else
{
break;
}
}
Console.WriteLine("End of C# caller method.");
}
private bool Rs008b_CSharp_ExceptionsAndRetry_Callee(ref int iIndex)
{
bool bReturnCode = true; // Means call this method again.
string[] sStrings = new string[4];
string sTemp;
sStrings[0] = "First array element.";
try
{
Console.WriteLine("At top of try block: " + iIndex.ToString());
sTemp = sStrings[iIndex];
Console.WriteLine( "The array element is: " + sTemp );
bReturnCode = false; // Means do not call this method again.
}
catch (Exception)
{
Console.WriteLine("In catch of -- Exception. Entering catch.");
++iIndex; // The 'ref' parameter in C#.
Console.WriteLine("In catch of -- Exception. Leaving catch.");
//retry;
// In C# we let the caller method do the work
// that the retry keyword does in X++.
}
Console.WriteLine("End of C# callee method.");
return bReturnCode;
}
}
Output
Berikut ialah output kepada konsol:
At top of try block: -1
In catch of -- Exception. Entering catch.
In catch of -- Exception. Leaving catch.
End of C# callee method.
At top of try block: 0
The array element is: First array element.
End of C# callee method.
End of C# caller method.
Perbandingan: Pengendali
Bahagian ini membandingkan pengendali antara X++ dan C#.
Pengendali Tugasan
Jadual berikut memaparkan perbezaan antara pengendali tugasan dalam X++ dan C#.
| X++ dan C# | Perbezaan |
|---|---|
= |
Dalam X++ pengendali ini menyebabkan penukaran tersirat apabila kehilangan ketepatan mungkin berlaku, seperti untuk tugasan daripada int64 kepada int. Tetapi dalam C# tugasan menyebabkan ralat kompilasi. |
+= dan -= |
Satu-satunya perbezaan ialah dalam C# pengendali ini juga digunakan dalam manipulasi perwakilan. |
| ++ dan -- | Ini ialah pengendali kenaikan dan penurunan dalam kedua-dua bahasa. Baris berikut adalah sama dalam kedua-dua bahasa:++myInteger;Tetapi dalam X++ kedua-dua pengendali ini adalah untuk pernyataan, bukan untuk ungkapan. Oleh itu baris berikut menjana ralat kompilasi dalam X++: myStr = int2str(++myInteger);myIntA = myIntBB++; |
Pengendali Aritmetik
Jadual berikut menyenaraikan pengendali aritmetik.
| X++ dan C# | Perbezaan |
|---|---|
| * | Sebagai pengendali pendaraban, tiada perbezaan. Ambil perhatian: Asterisk juga digunakan dalam pernyataan SQL yang merupakan sebahagian daripada bahasa X++. Dalam pernyataan SQL ini, tanda bintang juga boleh menjadi salah satu daripada yang berikut:
|
/ |
Pengendali bahagian adalah sama dalam X++ dan C#. |
MOD |
Untuk operasi modulo, satu-satunya perbezaan ialah simbol % digunakan dalam C#. |
| + | Pengendali penambahan adalah sama dalam X++ dan C#. Tanda tambah juga digunakan untuk penggabungan rentetan. Pengendali ini menambah nombor dan menggabungkan rentetan dalam kedua-dua bahasa. |
| - | Pengendali penolakan adalah sama dalam X++ dan C#. |
Pengendali Bitwise
Jadual berikut membandingkan pengendali bitwise antara X++ dan C#.
| X++ dan C# | Perbezaan |
|---|---|
| << | Pengendali anjakan kiri adalah sama dalam X++ dan C#. |
| >> | Pengendali anjakan kanan adalah sama dalam X++ dan C#. |
| ~ | Pengendali NOT dari segi bit adalah sama dalam X++ dan C#. |
| & | Pengendali binari AND adalah sama dalam X++ dan C#. |
| ^ | Pengendali XOR binari adalah sama dalam X++ dan C#. |
Pengendali Hubungan
Pengendali hubungan berikut adalah sama dalam X++ dan C#:
==<=<=><!=&&||!? :
Perbandingan: Peristiwa
Terdapat beberapa perbezaan dalam cara X++ dan C# melaksanakan corak reka bentuk peristiwa. Untuk maklumat lanjut, lihat Istilah Peristiwa dan Kata Kunci.
Perbandingan Peristiwa antara X++ dan C#
Terdapat perbezaan dalam cara perwakilan digunakan untuk acara dalam X++ berbanding C#.
| Konsep | X++ | C# | Komen |
|---|---|---|---|
| Wakil | Dalam X++, perwakilan boleh diisytiharkan hanya sebagai ahli dalam kelas. Seorang perwakilan tidak boleh menjadi ahli di atas meja. Semua perwakilan adalah ahli contoh kelas mereka, bukan ahli statik . Tiada pengubah suai akses boleh digunakan pada pengisytiharan perwakilan, kerana semua perwakilan adalah ahli yang dilindungi . Oleh itu, acara itu boleh dinaikkan hanya melalui kod dalam kelas yang sama di mana perwakilan adalah ahli. Walau bagaimanapun, satu pengecualian kepada sifat peribadi perwakilan ialah kod di luar kelas mereka boleh beroperasi pada perwakilan dengan menggunakan pengendali += dan -=. | Dalam C#, setiap perwakilan ialah jenis, sama seperti setiap kelas ialah jenis. Seorang perwakilan diisytiharkan secara bebas daripada mana-mana kelas. Tanpa kata kunci peristiwa , anda boleh mempunyai perwakilan sebagai jenis parameter pada kaedah, sama seperti anda boleh mempunyai kelas sebagai jenis parameter. Anda boleh membina tika perwakilan untuk dihantar untuk nilai parameter. | Dalam X++, setiap kelas ialah jenis, tetapi tiada perwakilan ialah jenis. Anda tidak boleh membina tika perwakilan. Tiada perwakilan boleh menjadi parameter untuk kaedah. Tetapi anda boleh mencipta kelas yang mempunyai ahli perwakilan dan anda boleh menghantar tika kelas sebagai nilai parameter. Untuk maklumat lanjut, lihat Kata Kunci X++. |
| Acara | Dalam kod X++, peristiwa ialah salah satu daripada yang berikut:
|
Dalam C#, kata kunci peristiwa digunakan untuk mengisytiharkan jenis perwakilan sebagai ahli kelas. Kesan kata kunci peristiwa adalah untuk menjadikan perwakilan dilindungi, namun masih boleh diakses oleh pengendali += dan -=. Anda boleh melanggan kaedah pengendali acara kepada acara dengan menggunakan pengendali +=. Perwakilan boleh berguna tanpa kata kunci peristiwa, sebagai teknik untuk menghantar penunjuk fungsi sebagai parameter ke dalam kaedah. | Peristiwa automatik yang berlaku sebelum permulaan kaedah, dan selepas tamat kaedah, boleh dilanggan hanya dengan menggunakan AOT. |
| += dan -= pengendali | Dalam X++, anda menggunakan pengendali += untuk melanggan kaedah kepada perwakilan. Pengendali -= menyahlanggan kaedah daripada perwakilan. | Dalam C#, anda menggunakan operator += untuk melanggan kaedah kepada acara atau kepada perwakilan yang tidak digunakan dengan kata kunci peristiwa . | Perwakilan mengandungi rujukan kepada semua objek yang mempunyai kaedah yang dilanggan kepada perwakilan. Objek tersebut tidak layak untuk kutipan sampah manakala perwakilan memegang rujukan tersebut. |
eventHandler |
Dalam X++, kata kunci eventHandler diperlukan apabila anda menggunakan sama ada pengendali += atau -= untuk melanggan atau menyahlanggan kaedah daripada perwakilan. |
System.EventHandler ialah jenis perwakilan dalam Rangka Kerja .NET. |
Istilah ini digunakan secara berbeza dalam X++ daripada C# atau Rangka Kerja .NET. Untuk maklumat lanjut, lihat Kata Kunci X++. |
Contoh X++
Perkara penting yang perlu diperhatikan ialah yang berikut dalam contoh X++:
Mempunyai
XppClassahli perwakilan yang dinamakanmyDelegate.Nota
AOT mengandungi nod untuk perwakilan. Nod terletak di AOT > Classes > XppClass > myDelegate. Beberapa nod pengendali acara boleh ditempatkan di bawah nod myDelegate. Pengendali peristiwa yang diwakili oleh nod dalam AOT tidak boleh dialih keluar oleh pengendali -= semasa masa jalan.
{} Pendakap gigi pada penghujung pengisytiharan perwakilan diperlukan, tetapi mereka tidak boleh mempunyai sebarang kod di dalamnya.
Mempunyai
XppClassdua kaedah yang tandatangan parameternya serasi dengan perwakilan. Satu kaedah adalah statik.Kedua-dua kaedah yang serasi ditambah kepada perwakilan dengan pengendali += dan kata kunci eventHandler . Pernyataan ini tidak memanggil kaedah pengendali peristiwa, pernyataan hanya menambah kaedah kepada perwakilan.
Acara ini dibangkitkan dengan satu panggilan kepada perwakilan.
Nilai parameter yang dihantar kepada perwakilan diterima oleh setiap kaedah pengendali peristiwa.
Kerja X++ pendek di bahagian atas contoh memulakan ujian.
// X++
// Simple job to start the delegate event test.
static void DelegateEventTestJob()
{
XppClass::runTheTest("The information from the X++ job.");
}
// The X++ class that contains the delegate and the event handlers.
class XppClass
{
delegate void myDelegate(str _information)
{
}
public void myEventSubscriberMethod2(str _information)
{
info("X++, hello from instance event handler 2: " + _information);
}
static public void myEventSubscriberMethod3(str _information)
{
info("X++, hello from static event handler 3: " + _information);
}
static public void runTheTest(str _stringFromJob)
{
XppClass myXppClass = new XppClass();
// Subscribe two event handler methods to the delegate.
myXppClass.myDelegate += eventHandler(myXppClass.myEventSubscriberMethod2);
myXppClass.myDelegate += eventHandler(XppClass::myEventSubscriberMethod3);
// Raise the event by calling the delegate one time,
// which calls all the subscribed event handler methods.
myXppClass.myDelegate(_stringFromJob);
}
}
Output daripada kerja X++ sebelumnya adalah seperti berikut:
X++, hello from static event handler
3: The information from the X++ job. X++, hello from instance event handler
2: The information from the X++ job.
Sampel C#
Bahagian ini mengandungi sampel kod C# untuk corak reka bentuk peristiwa sampel X++ sebelumnya.
// C#
using System;
// Define the delegate type named MyDelegate.
public delegate void MyDelegate(string _information);
public class CsClass
{
protected event MyDelegate MyEvent;
static public void Main()
{
CsClass myCsClass = new CsClass();
// Subscribe two event handler methods to the delegate.
myCsClass.MyEvent += new MyDelegate(myCsClass.MyEventSubscriberMethod2);
myCsClass.MyEvent += new MyDelegate(CsClass.MyEventSubscriberMethod3);
// Raise the event by calling the event one time, which
// then calls all the subscribed event handler methods.
myCsClass.MyEvent("The information from the C# Main.");
}
public void MyEventSubscriberMethod2(string _information)
{
Console.WriteLine("C#, hello from instance event handler 2: " + _information);
}
static public void MyEventSubscriberMethod3(string _information)
{
Console.WriteLine("C#, hello from static event handler 3: " + _information);
}
}
Output daripada sampel C# sebelumnya adalah seperti berikut:
CsClass.exe C#, hello from instance event handler
2: The information from the C\# Main. C\#, hello from static event handler
3: The information from the C\# Main.
Acara dan AOT
Terdapat sistem acara lain yang hanya digunakan untuk item dalam AOT. Untuk maklumat lanjut, lihat Nod Pengendali Peristiwa dalam AOT.
Perbandingan: Arahan Prakompilasi
X++ dan C# berkongsi beberapa kata kunci untuk sintaks arahan prapengkompilasi mereka, tetapi maknanya tidak selalu sama.
Persamaan
Pengkompil X++ dan C# mengenali banyak kata kunci yang sama. Dalam kebanyakan kes, kata kunci bermaksud sama untuk kedua-dua pengkompil bahasa.
Perbezaan
Perbezaan asas antara arahan prapengkompilasi dalam X++ berbanding C# ialah kata kunci #define yang diiktiraf oleh kedua-dua prapengkompilasi bahasa. Tidak seperti C#, dalam X++ arahan #define memerlukan titik dalam sintaksnya. Dalam X++, kurungan boleh digunakan untuk memberikan nilai kepada simbol yang ditakrifkan. Perbezaan ini ditunjukkan dalam contoh berikut:
- Dalam X++: #define. Tahun Awal (2003)
- Dalam C#: #define InitialYear
Perbezaan kecil ialah dalam C# boleh terdapat ruang dan aksara tab antara aksara # dan kata kunci arahan, seperti # tentukan Ujian.
Kata Kunci yang Serupa
Jadual berikut menyenaraikan arahan prapengkompilasi yang serupa dalam X++ dan C#.
| Kata kunci | X++ | C# | Komen |
|---|---|---|---|
#define |
Dalam X++, nama pembolehubah prapengkompilasi boleh ditakrifkan, dan nilai boleh diberikan kepada pembolehubah tersebut. | Dalam C#, nama pembolehubah prapengkompilasi boleh ditakrifkan, tetapi tiada nilai boleh diberikan kepada pembolehubah tersebut. Selain itu, sebarang #define dalam C# mesti berlaku di bahagian atas fail dan tidak boleh berlaku selepas sebarang kod seperti pernyataan menggunakan atau pengisytiharan kelas. | Pengkompil C# boleh memasukkan parameter /define baris arahan untuk mentakrifkan nama pembolehubah prapengkompilasi tanpa mentakrifkan pembolehubah dalam mana-mana fail kod C#. Pengkompil X++ tidak mempunyai rakan sejawat kepada /define. |
#if |
Dalam X++, #if boleh menentukan sama ada pembolehubah prapengkompil wujud, dan sama ada pembolehubah mempunyai nilai tertentu. | Dalam C#, #if hanya boleh menentukan sama ada pembolehubah prapengkompil wujud. Ia tidak boleh menguji sebarang nilai kerana tiada nilai boleh diberikan. | |
#endif |
Dalam X++, #endif menandakan penghujung blok #if. Ia juga menamatkan blok #ifnot. | Dalam C#, #endif menandakan penghujung blok #if, tanpa mengira sama ada blok itu termasuk #else. |
Kata Kunci Berbeza dengan Hasil Pemprosesan yang Sama
Jadual berikut menyenaraikan arahan prapengkompilasi yang dinamakan secara berbeza dalam X++ dan C#, tetapi yang memberikan hasil yang sama apabila diproses.
| X++ | C# | Komen |
|---|---|---|
| #ifnot | #if #else | Tiada arahan #else dalam X++, tetapi #ifnot menyediakan fungsi yang serupa. Dalam X++, #ifnot boleh menentukan sama ada pembolehubah prapengkompilasi wujud dan sama ada pembolehubah tidak mempunyai nilai tertentu yang diberikan. Dalam C#, #if boleh menentukan sama ada pembolehubah prapengkompil wujud apabila '!' simbol diawali kepada nama pembolehubah. |
//BP Deviation documented |
#pragma amaran | Entri X++ dan C# ini tidak setara, tetapi terdapat persamaan separa. Kedua-duanya menyekat mesej amaran pengkompilasi. |
| #macrolib | . Fail HPP dalam C++ | Terdapat persamaan separa antara arahan X++ #macrolib berbanding . Fail HPP dalam C++. Kedua-duanya boleh mengandungi beberapa pernyataan #define. |
Arahan Prakompilasi Eksklusif untuk X++
Jadual berikut menyenaraikan arahan prapengkompilasi X++ yang tidak mempunyai rakan sejawat langsung dalam C#.
| X++ | Komen |
|---|---|
| #linenumber | Arahan #linenumber adalah untuk mendapatkan nombor baris, supaya ia boleh dikeluarkan ke Infolog. #line arahan C# berbeza kerana tujuannya adalah untuk menetapkan nombor baris. |
| #defdec #definc | |
| #globaldefine | Dalam X++, terdapat perbezaan kecil antara #globaldefine berbanding #define. Perbezaannya ialah #globaldefine tidak pernah menimpa nilai bukan nol semasa yang diberikan kepada pembolehubah prapengkompilasi oleh #define. C# tidak mempunyai apa-apa yang serupa dengan perbezaan ini, kerana dalam C#, nama pembolehubah prapengkompilasi tidak boleh diberi nilai. |
| #localmacro #macro | Dalam X++, #localmacro membolehkan anda memperuntukkan nilai berbilang baris kepada pembolehubah prapengkompilasi. #macro adalah sinonim, tetapi #localmacro disyorkan. Dalam C#, arahan #define mempunyai sebahagian daripada fungsi ini, tetapi ia tidak boleh memperuntukkan nilai kepada pembolehubah prapengkompilasi. |
| #globalmacro | Dalam X++, #globalmacro hampir sama dengan #localmacro pilihan. |
Perbandingan: Pengaturcaraan Berorientasikan Objek
Prinsip pengaturcaraan berorientasikan objek (OOP) X++ berbeza daripada C#.
Perbandingan Konseptual
Jadual berikut membandingkan pelaksanaan prinsip OOP antara X++ dan C#.
| Ciri | X++ | C# | Komen |
|---|---|---|---|
| Lakonan | Bahasa X++ mempunyai kata kunci ialah dan sebagai, yang digunakan untuk menjadikan downcast selamat dan eksplisit. Petua: X++ tidak memerlukan penggunaan kata kunci sebagai apabila anda menurunkan pembolehubah kelas asas kepada pembolehubah kelas terbitan. Walau bagaimanapun, kami mengesyorkan agar semua pernyataan yang tertekan menggunakan kata kunci sebagai . | Objek boleh dilemparkan sama ada ke atas atau ke bawah laluan warisan. Downcasts memerlukan kata kunci sebagai . | Untuk maklumat lanjut tentang kata kunci X++ ialah dan sebagai, lihat Pengendali Ungkapan: Adakah dan Seperti untuk Warisan. |
| Fungsi tempatan | Kaedah boleh mengandungi pengisytiharan dan badan kod untuk sifar atau lebih fungsi tempatan. Hanya kaedah itu boleh mempunyai panggilan kepada fungsi tempatan. | C# 3.0 menyokong ungkapan lambda, yang mempunyai beberapa persamaan dengan fungsi tanpa nama dan fungsi tempatan. Ungkapan lambda sering digunakan dengan perwakilan. | |
| Kaedah beban berlebihan | Beban berlebihan kaedah tidak disokong. Nama kaedah boleh berlaku hanya sekali bagi setiap kelas. | Beban berlebihan kaedah disokong. Nama kaedah boleh berlaku berbilang kali dalam satu kelas, dengan tandatangan parameter yang berbeza dalam setiap kes. | X++ menyokong parameter pilihan pada kaedah. Parameter pilihan boleh meniru sebahagiannya beban berlebihan kaedah. Untuk maklumat lanjut, lihat baris untuk parameter pilihan dalam jadual ini. |
| Kaedah mengatasi | Kaedah penggantian disokong. Kelas terbitan boleh mempunyai kaedah dengan nama yang sama seperti dalam kelas asas, selagi tandatangan parameter adalah sama dalam kedua-dua kes. Satu-satunya pengecualian ialah kaedah ganti boleh menambah nilai lalai pada parameter. | Kaedah penggantian disokong. Kata kunci maya mesti digunakan pada kaedah sebelum kaedah boleh diganti dalam kelas terbitan. | Konsep mengatasi kaedah termasuk nama kaedah, tandatangan parameternya dan jenis pemulangannya. Konsep mengatasi kaedah tidak terpakai jika kaedah asas dan kaedah penggantian berbeza dalam mana-mana aspek ini. |
| Parameter pilihan | Pengisytiharan parameter boleh diikuti dengan tugasan nilai lalai. Pemanggil kaedah mempunyai pilihan untuk menghantar nilai untuk parameter tersebut, atau mengabaikan parameter untuk menerima nilai lalai. Ciri ini meniru beban berlebihan kaedah kerana dua panggilan ke nama kaedah yang sama boleh melepasi bilangan parameter yang berbeza. Setiap parameter yang mempunyai nilai lalai mesti mengikut parameter terakhir yang tidak mempunyai nilai lalai. | Parameter pilihan disokong oleh kata kunci params . Walaupun tanpa kata kunci params , dari sudut pandangan pemanggil, beban berlebihan kaedah boleh menyediakan fungsi yang sebahagiannya serupa. | Untuk maklumat lanjut, lihat Parameter dan Skop dan Menggunakan Parameter Pilihan. |
| Warisan tunggal | Anda boleh memperoleh kelas X++ anda daripada kelas X++ lain dengan menggunakan kata kunci lanjutan dalam nod classDeclaration kelas anda, dalam AOT. Tiada kelas yang diperoleh secara tersirat terus daripada kelas lain. Jika anda mahu kelas anda diperoleh secara langsung daripada Object kelas, anda mesti menggunakan kata kunci lanjutan . Anda boleh menentukan hanya satu kelas pada kata kunci lanjutan .Amaran: Apabila anda mengubah suai kelas asas X++ yang diperolehi oleh kelas lain, anda mesti menyusun semula kelas asas tersebut menggunakan Kompilasi ke hadapan. Pilihan ini memastikan bahawa kelas terbitan juga disusun semula. Untuk memastikan kelas terbitan juga disusun semula, klik kanan nod kelas asas dan kemudian klik Add-Ins > Kompilasi ke hadapan. Alternatif mengklik Bina > Kompilasi (atau menekan kekunci F7) kadangkala tidak mencukupi untuk perubahan kelas asas. Kelas boleh melaksanakan sifar hingga banyak antara muka. Jadual X++ secara tersirat mewarisi daripada Common jadual, dan daripada xRecord kelas. |
C# menggunakan kata kunci extends untuk diperoleh daripada kelas lain. Semua kelas .NET Framework secara tersirat berasal daripada System.Object kelas, melainkan ia secara eksplisit berasal daripada kelas lain. |
Perbandingan Kata Kunci
Jadual berikut menyenaraikan kata kunci berkaitan OOP dalam X++ dan C#.
| Kata kunci | X++ | C# | Komen |
|---|---|---|---|
| Abstrak | Tiada perbezaan. | ||
| Kelas | Pengubah suai awam dan swasta diabaikan pada pengisytiharan kelas. Tiada konsep pengelompokan kelas ruang nama. Tiada titik (.) dalam mana-mana nama kelas. | Pengubah suai awam dan swasta boleh digunakan untuk mengubah suai pengisytiharan kelas. C# juga mempunyai kata kunci dalaman, yang berkaitan dengan cara kelas dikumpulkan bersama dalam fail pemasangan. | Tidak ada konsep kelas yang dilindungi , hanya ahli kelas yang dilindungi . |
| Meluas | Pengisytiharan kelas boleh mewarisi daripada kelas lain dengan menggunakan kata kunci lanjutan . | Titik bertindih (:) digunakan di mana kata kunci memanjangkan dan melaksanakan digunakan dalam X++. | |
| Akhir | Kaedah akhir tidak boleh diganti dalam kelas terbitan. Kelas akhir tidak boleh dilanjutkan. | Kata kunci yang dimeterai pada kelas bermaksud perkara yang sama dengan maksud akhir pada kelas X++. | |
| Melaksanakan | Pengisytiharan kelas boleh melaksanakan antara muka dengan menggunakan kata kunci implements . | ||
| Antara muka | Antara muka boleh menentukan kaedah yang mesti dilaksanakan oleh kelas. | Antara muka boleh menentukan kaedah yang mesti dilaksanakan oleh kelas. | |
| baru | Kata kunci baharu digunakan untuk memperuntukkan tika baharu kelas. Kemudian pembina dipanggil secara automatik. Setiap kelas mempunyai tepat satu pembina, dan pembina dinamakan new. Anda boleh memutuskan parameter apa yang perlu dimasukkan oleh pembina. |
Kata kunci baharu digunakan untuk mencipta tika baharu kelas. Kemudian pembina dipanggil secara automatik. Kaedah pembina itu sendiri tidak dinamakan new, ia mempunyai nama yang sama dengan kelas.Ambil perhatian: Kata kunci baharu juga boleh digunakan pada kaedah, untuk mengubah suai cara kaedah mengatasi kaedah yang sama dalam kelas asas. |
Kedua-dua X++ dan C# menganggap pembina lalai untuk kelas yang tidak mempunyai pembina yang ditulis secara eksplisit dalam kod mereka. |
| Batal | Tiada perbezaan. | ||
| Persendirian dan Dilindungi | Kata kunci peribadi dan dilindungi boleh digunakan untuk mengubah suai pengisytiharan ahli kelas. | Kata kunci peribadi dan dilindungi boleh digunakan untuk mengubah suai pengisytiharan ahli kelas. | |
| Awam | Kaedah yang tidak diubah suai dengan awam, dilindungi atau peribadi mempunyai tahap akses lalai awam. | Kaedah yang tidak diubah suai dengan awam, dilindungi atau peribadi mempunyai tahap akses lalai peribadi. | |
| Statik | Kaedah boleh statik, tetapi medan tidak boleh. | Kedua-dua kaedah dan medan boleh menjadi statik. | |
| Super | Kata kunci super digunakan dalam kelas terbitan untuk mengakses kaedah yang sama pada kelas asasnya. void method2(){// Call method2 method// on the base class.super(); } |
Kata kunci asas digunakan dalam kelas terbitan untuk mengakses pelbagai kaedah dalam kelas asasnya. void method2() {// Call methods on// the base class.base.method2();base.method3(); } |
Dalam C#, terdapat sintaks khas untuk menggunakan asas untuk memanggil pembina asas. |
| Ini | Untuk panggilan daripada satu kaedah contoh ke kaedah lain pada objek yang sama, kelayakan untuk kaedah yang dipanggil diperlukan. Kata kunci ini tersedia sebagai kelayakan untuk objek semasa. | Untuk panggilan daripada satu kaedah contoh ke kaedah lain pada objek yang sama, kelayakan untuk kaedah yang dipanggil tidak diperlukan. Walau bagaimanapun, kata kunci ini tersedia sebagai kelayakan untuk objek semasa. Dalam amalan, kata kunci ini boleh membantu dengan memaparkan maklumat IntelliSense. | |
finalize |
Kelas Object mengandungi finalize kaedah.
finalize Kaedahnya tidak muktamad, dan ia boleh diganti. Kaedah ini finalize nampaknya menyerupai System.Object.Finalize kaedah dalam C#, tetapi dalam X++ kaedah itu finalize tidak mempunyai makna istimewa dalam apa jua bentuk. Objek dialih keluar secara automatik daripada memori apabila rujukan terakhir kepada objek berhenti merujuk objek. Sebagai contoh, ini boleh berlaku apabila rujukan terakhir keluar dari skop atau diberikan objek lain untuk dirujuk. |
Kaedah Finalize dan Dispose biasa pada beberapa jenis kelas. Pengumpul sampah memanggil Finalize kaedah dan Dispose apabila ia memusnahkan dan objek. |
Dalam C#, System.GC.Collect kaedah dalam Rangka Kerja .NET boleh dipanggil untuk memulakan pengumpul sampah. Tiada fungsi yang serupa dalam X++ kerana X++ menggunakan pengumpul sampah deterministik. |
main |
Kelas yang dipanggil daripada menu mempunyai kaedahnya main yang dipanggil oleh sistem. |
Kelas yang dipanggil daripada konsol baris arahan mempunyai kaedahnya Main yang dipanggil oleh sistem. |
Perbandingan: Kelas
Apabila anda menggunakan C# dalam Rangka Kerja .NET, kelas dikumpulkan ke dalam ruang nama. Setiap ruang nama memfokuskan pada kawasan berfungsi seperti operasi fail atau pantulan. Walau bagaimanapun, apabila anda menggunakan kelas dalam X++, tiada kumpulan yang boleh dilihat seperti ruang nama.
Perbandingan: Kelas tentang Refleksi
Dalam X++ TreeNode kelas menyediakan akses kepada Pokok Objek Aplikasi (AOT). Kelas ini TreeNode ialah pusat fungsi pantulan dalam X++. Kelas TreeNode dan kaedahnya boleh dibandingkan dengan System.Reflection ruang nama dalam Rangka Kerja .NET yang digunakan oleh C#.
Jadual berikut menyenaraikan beberapa kelas yang tersedia untuk anda apabila anda menulis kod C#. Ini ialah kelas Rangka Kerja .NET. Untuk jadual ini, semua kelas C# berada dalam ruang nama melainkan System.Reflection dinyatakan sebaliknya. Setiap baris menunjukkan kelas yang sepadan, atau ahli kelas, yang tersedia untuk anda apabila anda menulis kod X++.
| X++ | C# | Komen |
|---|---|---|
TreeNode |
System .Assembly |
Perhimpunan ialah kelas pertama yang digunakan apabila program C# mesti mengumpulkan maklumat refleksi. Kaedah statik pada kelas TreeNode X++ ialah titik permulaan untuk refleksi dalam X++. |
TreeNode |
System .Type |
Kaedah contoh pada TreeNode sepadan dengan kaedah contoh pada System.Type. |
TreeNode .AOTgetSource |
MethodInfo |
Kaedah ini AOTgetSource mengembalikan beberapa maklumat bersama-sama dalam satu rentetan. Ini termasuk kod sumber X++ dalam kaedah. Sebaliknya, MethodInfo mempunyai ahli yang berasingan untuk setiap maklumat. |
TreeNode .AOTfirstChild
TreeNode .AOTnextSibling
TreeNode .AOTiterator
AOTiterator
|
MethodInfo[] (tatasusunan) | Dalam C#, GetMethods kaedah pada System.Type mengembalikan tatasusunan objek MethodInfo. Anda boleh menggelung tatasusunan dengan teknik biasa untuk menambah pengindeks. Sebaliknya, model X++ adalah untuk menavigasi kawalan pokok AOT. Kaedah-kaedah TreeNodeAOTfirstChild dan AOTnextSibling mencapai navigasi. Sebagai alternatif yang setara, kelas X++ AOTiterator direka bentuk untuk menavigasi kawalan pokok AOT. Nod kelas ialah induk ke atas beberapa nod kaedah. Langkah-langkah AOTiterator melalui nod kanak-kanak, mengembalikan setiap satu sebagai contoh lain TreeNode . Sumber tambahan kaedah TreeNode yang dinamakan AOTparent dan AOTprevious. |
TreeNode .AOTgetProperty
TreeNode .AOTgetProperties
TreeNode .AOTname
|
PropertyInfo |
Dalam X++, kaedah mengembalikan AOTgetProperties rentetan panjang yang mengandungi pasangan nama-nilai untuk semua sifat TreeNode. Kaedah mengembalikan AOTname rentetan yang hanya mengandungi nilai untuk sifat nama. |
TreeNode .AOTsave
TreeNode .AOTinsert
|
System .Reflection .Emit (ruang nama kelas) |
Kaedah ini AOTsave menggunakan perubahan daripada TreeNode objek dalam kod X++ anda kepada AOT, dan perubahan dikekalkan. Untuk sampel kod yang besar, lihat Kaedah TreeNode.AOTsave. |
Perbandingan: Kelas tentang Fail IO
Terdapat beberapa kelas yang melaksanakan operasi input dan output fail (IO). Dalam Rangka Kerja .NET yang digunakan dalam C#, rakan sejawat kepada kelas ini berada dalam System.IO ruang nama.
Jadual berikut menyenaraikan beberapa kelas .NET Framework untuk C# yang berada dalam System.IO ruang nama. Setiap baris dalam jadual menunjukkan kelas atau kaedah X++ yang paling sepadan dengan kelas .NET Framework.
| X++ | C# | Komen |
|---|---|---|
BinaryIo |
FileStream
BinaryReader
BinaryWriter
|
Kelas X++ seperti yang BinaryIo memanjang daripada kelas Io abstrak berfungsi sebagai aliran, dan mereka juga berfungsi sebagai pembaca dan penulis untuk aliran itu. Dalam C#, strim ialah kelas berasingan daripada kelas yang mempunyai kaedah baca dan tulis yang lebih khusus. |
TextBuffer |
MemoryStream |
Kelas-kelas ini mengandungi penimbal dalam memori, dan beberapa kaedah menganggap penimbal seolah-olah ia adalah fail pada cakera keras. |
| WINAPI::createDirectory WINAPI::folderExists WINAPI::removeDirectory |
Directory
DirectoryInfo
Path
|
X++ boleh menggunakan kaedah statik dalam WINAPI kelas untuk banyak fungsi sistem pengendalian asas yang melibatkan direktori. |
| WINAPI::getDriveType |
DriveInfo
DriveType
|
Kelas dan kaedah ini digunakan untuk mendapatkan maklumat berkaitan pemacu. |
| WINAPI::copyFile WINAPI::createFile WINAPI::d eleteFile WINAPI::fileExists |
File
FileAttributes
FileInfo
|
X++ boleh menggunakan kaedah statik dalam WINAPI kelas untuk banyak fungsi sistem pengendalian asas yang melibatkan fail. |
CommaIo
Comma7Io
|
(Tiada kelas yang sepadan.) | Kelas X++ ini boleh menjana fail yang boleh diimport oleh Microsoft Excel. Dalam X++, rujukan perpustakaan EPPlus tersedia untuk interaksi tambahan dengan Excel. |
AsciiIo
TextIo
|
FileStream
TextReader
TextWriter
|
Kelas-kelas ini menggunakan halaman kod yang berbeza. |
Io |
Stream
StreamReader
StreamWriter
FileStream
|
Ini sering digunakan sebagai kelas asas yang dilanjutkan oleh kelas lain. |
CodeAccessPermission
FileIoPermission
|
System.Security
.CodeAccessPermission Ruang System.Security.Permissions nama termasuk kelas berikut:
|
Konsep dan kaedah assert, demand, dan revertAssert digunakan untuk kedua-dua bahasa. Walau bagaimanapun, deny kaedah dan revertDeny yang tersedia dalam C# tidak tersedia dalam X++. |
X++, Perbandingan SQL ANSI: Pilih SQL
Dalam X++, sintaks pernyataan pilih SQL berbeza daripada spesifikasi Institut Piawaian Kebangsaan Amerika (ANSI).
Pilih Jadual Tunggal
Jadual berikut menyenaraikan perbezaan antara pernyataan pilihan X++ SQL dan ANSI SQL.
| Ciri | X++ SQL | ANSI SQL | Komen |
|---|---|---|---|
| Nama jadual pada klausa daripada. | Klausa from menyenaraikan tika penimbal rekod yang diisytiharkan daripada jadual, seperti daripada CustTable jadual. |
Klausa daripada menyenaraikan nama jadual, bukan nama penimbal. | Penampan rekod mempunyai semua kaedah yang xRecordada pada kelas dalam X++. |
| Urutan sintaks susunan mengikut lawan di mana klausa. | Perintah demi klausa mesti muncul sebelum klausa di mana. Perintah mengikut klausa mesti muncul selepas klausa dari atau gabungan . Kumpulan mengikut klausa mesti mengikut peraturan kedudukan sintaks yang sama yang diikuti oleh susunan oleh. | Perintah mengikut klausa mesti muncul selepas klausa di mana. Klausa di mana mesti muncul selepas klausa dari atau gabung. | Dalam kedua-dua X++ dan ANSI SQL, klausa daripada dan cantum mesti muncul sebelum klausa pesanan oleh dan di mana . |
| Penafian keadaan. | Tanda seru ('!') digunakan untuk penafian. | Kata kunci not digunakan untuk penafian. | X++ tidak menyokong sintaks !like. Sebaliknya, anda mesti menggunakan ! pengendali kepada klausa. |
| Aksara kad bebas untuk pengendali serupa . | 0 kepada banyak – Asterisk ('*') Tepat 1 – Tanda soal ('?') |
0 kepada banyak – Tanda peratus ('%') Tepat 1 – Underbar ('_') |
|
| Pengendali logik dalam klausa where . | Dan – && Atau – || |
Dan – dan Atau – atau |
Contoh Kod
Contoh kod berikut menggambarkan ciri dalam jadual sebelumnya.
static void OByWhere452Job(Args _args)
{
// Declare the table buffer variable.
CustTable tCustTable;
;
while
SELECT * from tCustTable
order by tCustTable.AccountNum desc
where (!(tCustTable.Name like '*i*i*') && tCustTable.Name like 'T?e *')
{
info(tCustTable.AccountNum + " , " + tCustTable.Name);
}
}
/*** InfoLog output
Message (04:02:29 pm)
4010 , The Lamp Shop
4008 , The Warehouse
4001 , The Bulb
***/
Kata Kunci SQL X++
Kata kunci SQL X++ berikut adalah antara kata kunci yang bukan sebahagian daripada ANSI SQL:
- Silang syarikat
- firstonly100
- forceliterals
- gelung bersarang paksa
- Pemegang ForcePlace
- force selectorder
- validtimestate
Klausa Sertai
Jadual berikut menyenaraikan perbezaan tentang kata kunci cantum X++ SQL dan ANSI SQL.
| Ciri | X++ SQL | ANSI SQL | Komen |
|---|---|---|---|
| Senarai lajur. | Lajur dalam senarai lajur mestilah semuanya datang daripada jadual yang disenaraikan dalam klausa daripada, dan bukan daripada mana-mana jadual dalam klausa cantuman . Lajur dalam senarai tidak boleh dilayakkan mengikut nama jadualnya. | Lajur dalam senarai lajur boleh datang daripada mana-mana jadual dalam klausa daripada atau cantuman . Ia membantu orang lain mengekalkan kod anda apabila anda melayakkan lajur dalam senarai dengan nama jadual mereka. | Untuk maklumat lanjut, lihat Pilih Penyata pada Medan. |
| Sertai sintaks klausa. | Klausa cantum mengikut klausa where . | Klausa cantum mengikut jadual dalam klausa daripada. | Dalam contoh kod X++, kriteria cantuman ialah persamaan SalesPoolId nilai. |
| Kata kunci dalaman . | Mod cantuman lalai ialah cantuman dalaman. Tiada kata kunci dalaman . | Mod cantuman lalai ialah cantuman dalaman. Kata kunci dalaman tersedia untuk menjadikan kod eksplisit. | Kata kunci luar wujud dalam kedua-dua X++ SQL dan ANSI SQL. |
| Kata kunci kiri dan kanan . | Kata kunci kiri dan kanan tidak tersedia. Semua cantuman ditinggalkan. | Kata kunci kiri dan kanan tersedia untuk mengubah suai kata kunci gabungan . | Tiada komen. |
| Pengendali kesaksamaan. | Pengendali tanda sama berganda ('==') digunakan untuk menguji kesamaan dua nilai. |
Pengendali tanda sama tunggal ('=') digunakan untuk menguji kesamaan dua nilai. |
Tiada komen. |
Contoh Kod
Contoh kod berikut menggambarkan sintaks cantuman dalam X++ SQL.
static void OByWhere453Job(Args _args)
{
// Declare table buffer variables.
CustTable tCustTable;
SalesPool tSalesPool;
;
while
SELECT
// Not allowed to qualify by table buffer.
// These fields must be from the table
// in the from clause.
AccountNum,
Name
from tCustTable
order by tCustTable.AccountNum desc
where (tCustTable.Name like 'The *')
join tSalesPool
where tCustTable.SalesPoolId == tSalesPool.SalesPoolId
{
info(tCustTable.AccountNum + " , " + tCustTable.Name);
}
}
Medan Agregat
Jadual berikut menyenaraikan beberapa perbezaan dalam cara medan agregat dalam senarai lajur pilih dirujuk antara X++ SQL dan ANSI SQL. Medan agregat ialah medan yang diperoleh oleh fungsi seperti jumlah atau purata.
| Ciri | X++ SQL | ANSI SQL | Komen |
|---|---|---|---|
| Alias nama medan agregat. | Nilai agregat berada dalam medan yang diagregatkan. | Anda boleh menggunakan kata kunci sebagai untuk mengetag medan agregat dengan nama alias. Alias boleh dirujuk dalam kod berikutnya. | Untuk maklumat lanjut, lihat Fungsi Agregat: Perbezaan Antara X++ dan SQL |
Contoh Kod
Dalam contoh kod berikut, panggilan kepada kaedah maklumat menggambarkan cara untuk merujuk medan agregat (lihat tPurchLine.QtyOrdered).
static void Null673Job(Args _args)
{
PurchLine tPurchLine;
;
while
select
// This aggregate field cannot be assigned an alias name.
sum(QtyOrdered)
from tPurchLine
{
info(
// QtyOrdered is used to reference the sum.
"QtyOrdered: " + num2str(tPurchLine.QtyOrdered,
3, // Minimum number of output characters.
2, // Required number of decimal places in the output.
1, // '.' Separator to mark the start of the decimal places.
2 // ',' The thousands separator.
));
}
info("End.");
}
/***
Message (12:23:08 pm)
QtyOrdered: 261,550.00
End.
***/
Perbezaan Lain
Jadual berikut menyenaraikan perbezaan lain bagi pernyataan pilih antara X++ SQL dan ANSI SQL.
| Ciri | X++ SQL | ANSI SQL | Komen |
|---|---|---|---|
| Mempunyai kata kunci. | Tidak ada kata kunci . | Kata kunci mempunyai membolehkan anda menentukan kriteria penapis untuk baris yang dijana oleh klausa kumpulan oleh. | Tiada komen. |
| Keputusan batal. | Dalam seketika, seketika , jika klausa di mana menapis semua baris, tiada baris kiraan khas dikembalikan untuk melaporkannya. | Dalam pilih, jika klausa where menapis semua baris, baris kiraan khas dikembalikan. Nilai kiraan ialah 0. | Tiada komen. |
| Kursor untuk menavigasi baris yang dikembalikan. | Pernyataan sementara pilih menyediakan fungsi kursor. Alternatifnya ialah menggunakan kata kunci seterusnya . | Anda boleh mengisytiharkan kursor untuk menggelung melalui baris yang dikembalikan daripada pernyataan pilih . | |
| Daripada klausa. | Kata kunci from adalah pilihan apabila tiada lajur disenaraikan dan hanya satu jadual dirujuk. Dua pilihan sintaks berikut adalah setara: select \* from tCustTable; select tCustTable; |
Pernyataan pilih tidak boleh dibaca daripada jadual melainkan klausa from digunakan. | Dalam X++ SQL, pernyataan pilih mudah mengisi pembolehubah penimbal jadual dengan baris pertama yang dikembalikan. Ini digambarkan oleh serpihan kod berikut: select \* from tCustTable; info(tCustTable.Name); |