Czym są drzewa wyrażeń
Poznaj kod reprezentowany jako struktura danych.
Czym są drzewa wyrażeń to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.
Kod jako dane
Drzewo wyrażeń reprezentuje kod jako strukturę danych, którą można analizować w czasie wykonywania, zamiast jako skompilowane instrukcje, które można tylko uruchomić. W języku C# służy do tego Expression<TDelegate>.
Lambda jako delegat a drzewo
Przypisanie lambdy do Func<...> daje kod, który można uruchomić. Przypisanie tej samej lambdy do Expression<Func<...>> powoduje, że kompilator tworzy opisujące ją drzewo.
using System;
using System.Linq.Expressions;
Func<int, int> runnable = x => x + 1; // compiled delegate
Expression<Func<int, int>> tree = x => x + 1; // data structure
Console.WriteLine(runnable(5)); // 6
Console.WriteLine(tree); // x => (x + 1)Analizowanie drzewa
Ponieważ drzewo wyrażeń jest danymi, można odczytać jego elementy: parametry, treść oraz typ węzła.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + 1;
Console.WriteLine(tree.Parameters[0].Name); // x
Console.WriteLine(tree.Body.NodeType); // Add
Console.WriteLine(tree.ReturnType); // System.Int32Hierarchia wyrażeń
Każdy węzeł dziedziczy po System.Linq.Expressions.Expression. Do często używanych typów należą BinaryExpression, ParameterExpression, ConstantExpression i MethodCallExpression.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + 1;
var body = (BinaryExpression)tree.Body;
Console.WriteLine(body.Left); // x
Console.WriteLine(body.Right); // 1Dozwolone są tylko lambdy wyrażeniowe
W drzewo można przekształcić tylko lambdę zawierającą pojedyncze wyrażenie. Lambdy z treścią w postaci instrukcji, czyli z nawiasami klamrowymi, nie mogą być drzewami wyrażeń.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> ok = x => x * 2; // fine
// Expression<Func<int,int>> bad = x => { return x*2; }; // compile error
Console.WriteLine(ok); // x => (x * 2)Dlaczego to ma znaczenie
Drzewa wyrażeń pozwalają bibliotekom rozumieć kod, a nie tylko go uruchamiać. Dostawcy LINQ tłumaczą je na SQL, zapytania dynamiczne lub inne języki docelowe.
NodeType określa operację
Właściwość NodeType jest wartością wyliczenia ExpressionType, która określa operację reprezentowaną przez dany węzeł.
using System;
using System.Linq.Expressions;
Expression<Func<int, bool>> tree = x => x > 10;
Console.WriteLine(tree.Body.NodeType); // GreaterThanStałe i parametry
ParameterExpression reprezentuje dane wejściowe, a ConstantExpression przechowuje wartość literału osadzoną w kodzie.
using System;
using System.Linq.Expressions;
Expression<Func<int, int>> tree = x => x + 5;
var body = (BinaryExpression)tree.Body;
Console.WriteLine(body.Left.GetType().Name); // ParameterExpression (or TypedParameterExpression)
Console.WriteLine(((ConstantExpression)body.Right).Value); // 5Wywołania metod w drzewach
Lambda wywołująca metodę staje się obiektem MethodCallExpression, który udostępnia metodę i jej argumenty.
using System;
using System.Linq.Expressions;
Expression<Func<string, int>> tree = s => s.Length;
// member access here; a call example:
Expression<Func<string, string>> call = s => s.ToUpper();
var mc = (MethodCallExpression)call.Body;
Console.WriteLine(mc.Method.Name); // ToUpperDrzewa są niemodyfikowalne
Drzewa wyrażeń są niemodyfikowalne. Aby je „zmienić”, należy zbudować nowe drzewo z ich elementów — na tej zasadzie działają odwiedzający i mechanizmy przepisywania.
Zastosowanie w praktyce
Przeanalizujemy od początku do końca małe drzewo predykatu: parametr, operator i stałą.
using System;
using System.Linq.Expressions;
Expression<Func<int, bool>> isAdult = age => age >= 18;
var body = (BinaryExpression)isAdult.Body;
Console.WriteLine(isAdult.Parameters[0].Name); // age
Console.WriteLine(body.NodeType); // GreaterThanOrEqual
Console.WriteLine(((ConstantExpression)body.Right).Value); // 18Szybkie sprawdzenie
Proszę sprawdzić, co wyróżnia drzewo wyrażeń.
Podsumowanie
Poznano pojęcie drzew wyrażeń.
Expression<TDelegate>reprezentuje kod jako dane, które można analizować.- Węzły obejmują parametry, stałe, operatory binarne i wywołania metod.
- Kwalifikują się tylko lambdy zawierające pojedyncze wyrażenie.
- Drzewa są niemodyfikowalne, a ich przepisywanie tworzy nowe drzewa.
Często zadawane pytania
Czy lekcja „Czym są drzewa wyrażeń” jest bezpłatna?
Tak — pełny tekst „Czym są drzewa wyrażeń” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Czym są drzewa wyrażeń”?
Poznaj kod reprezentowany jako struktura danych. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C# Academy?
Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Czym są drzewa wyrażeń”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?
Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Czym są drzewa wyrażeń
- Ręczne tworzenie wyrażeń
- Kompilowanie i wykonywanie wyrażeń
- Drzewa wyrażeń w dostawcach LINQ