TGViewer
DotNetZoom DotNetZoom @dotnetzoom · 2.82K subscribers
Post #1255 3.12K

Forwarded from DotNetZoom (محمد جواد ابراهیمی)

✅ مفهوم Expression Tree در دات نت

میشه گفت یکی از advanced ترین قسمت های دات نت، مفهوم Expression Tree و کلاس Expression هست که یه جورایی قلب IQueryable رو هم تشکیل میده
شاید نهایت استفاده افراد، کار با <<Expression<Func برای شرط های predicate بر روی متد Where و یا selector برای متد Select باشه
ولی Expression خیلی بزرگتر از اینهاست

🔸درواقع مفهوم Expression Tree به مجموعه از از node ها در قالب یک ساختار درختی گفته میشه که هر node اون، خود یک Expression هست. اما خود Expression چیه؟
درواقع هر Expression یک operation (عملیات) برنامه نویسی رو بیان میکنه. توسط کلاس Expression در دات نت میتوان برای هر عملیات برنامه نویسی یک expression ساخت.

🔹به عنوان مثال:
- تعریف یک variable (متغیر)، constant یا parameter (پارامتر ورودی متد)
- انتصاب یک مقدار به یک variable یا parameter
- جمع، تفریق، ضرب، تقسیم و... کردن دو مقدار
- تعریف یک شرط (if/else) یا سویچ (switch) منطقی
- تعریف یک حلقه (for یا while)
- بازگرداندن (return کردن) خروجی متد
- فراخوانی یک متد، پاس دادن پارامتر های ورودی و گرفتن مقدار خروجی
- و... اکثر کار هایی که شما توسط کد نویسی میتونین انجام بدین

🔸فرق expression با کد نویسی معمولی برای operation های برنامه نویسی اینه که توسط Expression میتوان یک ساختار (data structure) قابل توصیف برای کد ها ایجاد کرد.
در نتیجه میتوان از روی این ساختار قابل توصیف، کار های متفاوت و خلاقانه ای انجام داد. مثلا میشه از روی ساختار کد هامون Transpilation انجام بدیم و کوئری (مثلا SQL) معادل اون رو تولید کرد.

🔹در واقع هنگامی که شما یک عبارت lambda رو به یکی از متد های linq که ورودی <Expression<Func داره پاس میدین، پشت صحنه به هنگام Compile یک LambdaExpression از روی عبارت lambda شما ساخته میشه و اون هست که به متد شما پاس داده میشه.
چرا؟ چون که ساختار کد شما رو لازم داره تا بتونه از روی اون Transpilation انجام بده و کوئری (مثلا SQL) معادل اون رو تولید کنه. (این مثال رو ببینید)

🔸یا حتی میتوان به کمک Transpilation، از روی یک expression یک عبارت readable (خوانا) جهت توصیف کاری که قراره انجام بده تولید کرد. همانند کاری که کتابخانه ReadableExpressions کرده و توسط افزونه ویژوال استادیو ReadableExpressions.Visualizers این امکان رو میده که به هنگام دیباگ بتونین یک readable view از روی expression هاتون ببینید

🔹کار دیگه ای که توسط Expression میشه انجام داد. تولید کد IL (مخفف Intermediate Language) از روی اون هست. مثلا شما نمیتونین توسط Reflection حتی، یک متد جدید (شامل مجمومه ای از operation ها) ایجاد کنین ولی توسط Expression میتونین به جای اینکه کد شما به هنگام compile تبدیل به IL بشه، اون رو به هنگام run-time (در زمان اجرای برنامه) از روی همون expression (که یک ساختار قابل توصیف از یک تیکه کد هست) به کد IL تبدیل کنین یا اصطلاحات Emit کنین (بیرون بدین)
در نتیجه میتونین به هنگام run-time کد جدید تولید کنین و این همون تکنیکی هست که کتابخانه های Object Mapper از جمله AutoMapper و Mapster و... از اون استفاده میکنن

🔸گفتم Emit، جا داره از Reflection.Emiit هم یادی بکنیم که پایه ای ترین روش برای تولید کد IL در زمان run-time هست و میشه Expression رو به عنوان یک wrapper روی Reflection.Emit محسوب کرد که کار با اون رو ساده تر میکنه. هرچند کار هایی میشه با Reflection.Emit انجام داد که توسط Expression Tree نمیشه انجام داد (و بلعکس) پس اینجا به هیچ عنوان جایگزین هم نیستند بلکه فقط توی تولید کد IL وجه مشترک دارند.

🔰 جمع بندی
قابلیت Expression Tree یک قابلیت پیشرفته هست و نیاز اکثر افراد نمیشه ولی مزایای غیر قابل چشم پوشی ایی رو به ما میده که حرفه ای ها میتونین کار جالبی باهاش بکنن. توسط این قابلیت که یکی از جذاب ترین امکانات دات نت هست میتونین کار های جالبی انجام بدین از جمله:
1️⃣ گردش روی node ها و فهمیدن ساختار کد (MetaProgramming)
2️⃣ ترجمه کد ها به یک زبان دیگر (Transpilation)
3️⃣ تولید کد IL از روی اون (Code Generation)

💎در آخر یکی از بهترین مقالاتی که این مفهوم رو به خوبی به همراه مثال توضیح داده مقاله زیر هست که پیشنهاد میکنم حتما بخونین
https://tyrrrz.me/blog/expression-trees
____________________
@DotNetZoom
Oleksii Holub Working with Expression Trees in C# • Oleksii Holub Expression trees is an obscure, although very interesting feature in .NET. Most people probably think of it as something synonymous with object-relational mapping frameworks, but despite being its most common use case, it's not the only one. There are a…
More from @dotnetzoom
  1. Dec 27, 2021امکانات LINQ در NET 6. ✅ ۱- امکان مشخص کردن مقدار پیش‌فرض در OrDefault* var item1 = list1.…
  2. Dec 6, 2021انتقال داده ها به واسطه Azure Service Bus امروزه سرعت انتقال داده‌ها از اهمیت بالایی برخور…
  3. Nov 29, 2021اضافه شدن قابلیت Temporal Table به EF Core 6 ➖ مایکروسافت در سال 2016 قابلیت Temporal Tabl…
  4. Nov 10, 2021همه چیز در مورد NET Core 6. دیروز نسخه رسمی NET Core 6. به همراه نسخه رسمی Visual Studio 2…
  5. Nov 10, 2021نسخه نهایی NET 6.0 منتشر شد. نسخه 6.0 دات نت به صورت طولانی مدت پشتیبانی میشود (LTS) و توس…
  6. Nov 8, 2021کنفرانس NET. Conf هر سال خبرهای هیجان‌انگیزی داره. امسال هم NET. خبر های خوب و جذابی داره…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →