Bagikan melalui


Pohon Ekspresi

Pohon ekspresi mewakili kode dalam struktur data seperti pohon, di mana setiap simpul adalah ekspresi, misalnya, panggilan metode atau operasi biner seperti x < y.

Jika Anda menggunakan LINQ, Anda memiliki pengalaman dengan pustaka kaya di mana jenis Func adalah bagian dari rangkaian API. (Jika Anda tidak terbiasa dengan LINQ, Anda mungkin ingin membaca tutorial LINQ dan artikel tentang ekspresi lambda sebelum yang satu ini.) Pohon Ekspresi menyediakan interaksi yang lebih kaya dengan argumen yang merupakan fungsi.

Anda menulis argumen fungsi, biasanya menggunakan Ekspresi Lambda, saat Anda membuat kueri LINQ. Dalam kueri LINQ umum, argumen fungsi tersebut diubah menjadi delegasi yang dibuat kompilator.

Anda sudah menulis kode yang menggunakan pohon Ekspresi. API LINQ Entity Framework menerima pohon Ekspresi sebagai argumen untuk Pola Ekspresi Kueri LINQ. Itu memungkinkan Kerangka Kerja Entitas untuk menerjemahkan kueri yang Anda tulis di C# ke SQL yang dijalankan di mesin database. Contoh lain adalah Moq, yang merupakan kerangka kerja tiruan populer untuk .NET.

Saat Anda ingin memiliki interaksi yang lebih kaya, Anda perlu menggunakan Pohon Ekspresi. Pohon Ekspresi mewakili kode sebagai struktur yang Anda periksa, ubah, atau jalankan. Alat-alat ini memberi Anda kekuatan untuk memanipulasi kode selama run time. Anda menulis kode yang memeriksa algoritma yang sedang berjalan, atau menyuntikkan kemampuan baru. Dalam skenario yang lebih canggih, Anda memodifikasi algoritma yang sedang berjalan dan bahkan menerjemahkan ekspresi C# ke dalam bentuk lain untuk eksekusi di lingkungan lain.

Anda mengkompilasi dan menjalankan kode yang diwakili oleh pohon ekspresi. Membangun dan menjalankan pohon ekspresi memungkinkan modifikasi dinamis kode yang dapat dieksekusi, eksekusi kueri LINQ di berbagai database, dan pembuatan kueri dinamis. Untuk informasi selengkapnya tentang pohon ekspresi di LINQ, lihat Cara menggunakan pohon ekspresi untuk membangun kueri dinamis.

Pohon ekspresi juga digunakan dalam runtime bahasa dinamis (DLR) untuk memberikan interoperabilitas antara bahasa dinamis dan .NET dan untuk memungkinkan penulis kompilator memancarkan pohon ekspresi alih-alih bahasa perantara Microsoft (CIL). Untuk informasi selengkapnya tentang DLR, lihat Gambaran Umum Runtime Bahasa Dinamis.

Anda dapat membuat pengompilasi C# atau Visual Basic membuat pohon ekspresi untuk Anda berdasarkan ekspresi lambda anonim, atau Anda dapat membuat pohon ekspresi secara manual dengan menggunakan System.Linq.Expressions namespace.

Saat ekspresi lambda ditetapkan ke variabel jenis Expression<TDelegate>, pengkompilasi memancarkan kode untuk membangun pohon ekspresi yang mewakili ekspresi lambda.

Contoh kode berikut menunjukkan cara membuat pengkompilasi C# membuat pohon ekspresi yang mewakili ekspresi num => num < 5lambda .

Expression<Func<int, bool>> lambda = num => num < 5;

Anda membuat pohon ekspresi dalam kode Anda. Anda membangun pohon dengan membuat setiap simpul dan melampirkan simpul ke dalam struktur pohon. Anda mempelajari cara membuat ekspresi dalam artikel tentang membangun pohon ekspresi.

Pohon ekspresi tidak dapat diubah. Jika Anda ingin mengubah pohon ekspresi, Anda harus membuat pohon ekspresi baru dengan menyalin yang sudah ada dan mengganti simpul di dalamnya. Anda menggunakan visitor pohon ekspresi untuk menelusuri pohon ekspresi yang ada. Untuk informasi selengkapnya, lihat artikel tentang menerjemahkan pohon ekspresi.

Setelah membuat pohon ekspresi, Anda menjalankan kode yang diwakili oleh pohon ekspresi.

Keterbatasan

Kompiler C# menghasilkan pohon ekspresi hanya dari ekspresi lambda (atau lambda satu baris). Ini tidak dapat mengurai pernyataan lambda (atau lambda multibaris). Untuk informasi selengkapnya tentang ekspresi lambda di C#, lihat Ekspresi Lambda.

Ada beberapa elemen bahasa C# yang lebih baru yang tidak diterjemahkan dengan baik ke dalam pohon ekspresi. Pohon ekspresi tidak boleh berisi await ekspresi, atau async ekspresi lambda. Banyak fitur yang ditambahkan dalam C# 6 dan yang lebih baru tidak muncul persis seperti yang ditulis dalam pohon ekspresi. Sebagai gantinya, fitur yang lebih baru diekspos dalam pohon ekspresi dalam sintaks yang setara dan lebih lama, jika memungkinkan. Struktur lain tidak tersedia. Ini berarti bahwa kode yang menginterpretasikan pohon ekspresi berfungsi sama ketika fitur bahasa baru diperkenalkan. Namun, bahkan dengan batasan ini, pohon ekspresi memungkinkan Anda membuat algoritma dinamis yang mengandalkan interpretasi dan modifikasi kode yang diwakili sebagai struktur data. Ini memungkinkan pustaka kaya seperti Entity Framework untuk mencapai apa yang mereka lakukan.

Pohon ekspresi tidak akan mendukung jenis node ekspresi baru. Ini akan menjadi perubahan besar bagi semua library yang menafsirkan pohon ekspresi dengan memperkenalkan jenis node baru. Daftar berikut ini mencakup sebagian besar elemen bahasa C# yang tidak dapat digunakan: