Skip to main content
SEMastery
.NET Coreintermediate

Dynamic Code Execution in .NET with C# Eval Expression

Learn how to run C# code at runtime using the C# Eval Expression library with simple Execute and Compile examples for beginners.

12 min readUpdated February 6, 2026

Imagine you run a small sweet shop. You have a printed price list, and every time the price of laddu changes, you must print a brand new list. That is slow and wastes paper. Now imagine a small chalkboard next to the till. When a price changes, you just rub out the old number and write the new one. The shop keeps working. No reprinting. No closing for the day.

Most C# code is like the printed price list. You write it, you build it, and you ship it. To change anything, you build and ship again. But sometimes you want a chalkboard instead, a place where a rule can change while the program is still running. That is what dynamic code execution gives you. And the C# Eval Expression library is one of the friendliest ways to do it in .NET.

In this guide you will learn what dynamic code execution means, when it helps, and how to use the two main tools the library gives you: Eval.Execute and Eval.Compile. We will keep things simple and gentle, with plenty of small examples.

What does "dynamic code execution" mean?

Normally, C# code is turned into a runnable program before it runs. This happens at compile time, on your machine or a build server. Once the program starts, the code is fixed.

Dynamic code execution flips this around. You hand the program a piece of code written as a plain string, and the program turns that string into something it can run, right now, while it is already running. This moment is called runtime.

Here is the difference in one picture.

Normal code is fixed when the program starts. Dynamic code is built while the program runs.

The key idea: with a normal program, the rule lives in the source file. With dynamic code, the rule can live in a database, a config file, or even a text box, and you can change it without rebuilding.

Meet the C# Eval Expression library

The C# Eval Expression library (its NuGet package is named Z.Expressions.Eval) is built by ZZZ Projects. It lets you evaluate, compile, and run C# code and expressions at runtime. It understands a huge slice of normal C#: math, strings, booleans, LINQ, lambdas, your own classes, and more.

To start, you add the package to your project.

// In your terminal, inside the project folder:
// dotnet add package Z.Expressions.Eval
 
using Z.Expressions; // This namespace gives you Eval.Execute and Eval.Compile

One important note for honesty: the library is free up to 50 characters for both the Execute and Compile methods. That is enough to learn and to run small expressions. Longer expressions need a paid license. Always check the current pricing before you ship something big.

Your first evaluation with Eval.Execute

The simplest tool is Eval.Execute. You give it a string of C# code, and it runs that code and gives you back the answer.

using Z.Expressions;
 
// Run a tiny math expression written as a string
int result = Eval.Execute<int>("1 + 2");
Console.WriteLine(result); // 3

Notice the <int> part. That tells the library "the answer will be an int, please give it back to me as an int." This is called the generic variant. There is also a plain version, Eval.Execute("1 + 2"), that returns an object, but using the typed version is clearer and safer.

The string "1 + 2" is not special to C# when your program is built. It is just text. The library reads that text at runtime and figures out what it means. That is the magic.

Passing values into your expression

A fixed sum like "1 + 2" is not very useful. The real power shows up when you pass in values. The library lets you hand over an object, and then your expression can use the names of that object's members.

using Z.Expressions;
 
// X and Y come from an anonymous object
int result = Eval.Execute<int>("X + Y", new { X = 1, Y = 2 });
Console.WriteLine(result); // 3

Here we passed new { X = 1, Y = 2 }. The library automatically registers the names X and Y, so the expression "X + Y" knows what they mean. You can pass many kinds of value holders.

Way to pass valuesExampleGood for
Anonymous objectnew { X = 1, Y = 2 }Quick, simple cases
Your own classnew Order { Total = 500 }Real business objects
Dictionarynew Dictionary<string, object>Names known only at runtime
ExpandoObjectdynamic bag of valuesFlexible, loose data

This flexibility is what makes the library feel friendly. You do not have to twist your data into a special shape. You pass what you already have.

How Eval.Execute handles your call

String
Values
Parse
Run
Answer

Steps

1

String

Your C# code as text

2

Values

An object with named members

3

Parse

Library reads the code

4

Run

Code executes at runtime

5

Answer

Typed result returns to you

The journey of a single expression from string to answer.

A slightly bigger example with LINQ

The library is not limited to small sums. It understands LINQ, lambdas, and collections too. Here is a filter that keeps only the numbers in a range.

using Z.Expressions;
 
var result = Eval.Execute<List<int>>(
    "new List<int> { 1, 2, 3, 4, 5 }.Where(x => x > MinValue && x < MaxValue).ToList()",
    new { MinValue = 1, MaxValue = 5 }
);
 
// result holds 2, 3, 4
Console.WriteLine(string.Join(", ", result));

Read that slowly. The whole LINQ query lives inside a string. The MinValue and MaxValue come from the object we passed. The library runs the lambda x => x > MinValue && x < MaxValue for each number. This is the same C# you already know, just written as text and run later.

When running once is wasteful: meet Eval.Compile

Eval.Execute does a lot of work each time you call it. It reads the string, understands it, and runs it. If you only do this once, that is fine. But what if you must run the same expression thousands of times with different inputs? Reading the string every single time would be slow.

This is where Eval.Compile shines. It reads the string once and gives you back a ready-to-use function, called a delegate. After that, you call the delegate directly, with no re-reading. The official docs note this can be up to 1000x quicker than calling Execute over and over.

using Z.Expressions;
 
// Compile once: build a Func that takes an int and returns a string
var compiled = Eval.Compile<Func<int, string>>(
    "i % 15 == 0 ? i + \" => FizzBuzz\" : i.ToString()",
    "i"
);
 
// Call the delegate many times, fast
for (int i = 1; i <= 5; i++)
{
    Console.WriteLine(compiled(i));
}

The "i" at the end names the parameter, so the expression knows that i is the incoming number. The result type Func<int, string> says "this takes an int and gives back a string." Once you hold compiled, calling it is just like calling any normal method.

Here is the difference in cost between the two approaches.

Execute does the heavy reading work every time. Compile does it once.

Execute vs Compile: which should you pick?

A simple rule helps you choose.

QuestionUse ExecuteUse Compile
How often do you run it?OnceMany times
Does the expression change often?YesNo, it is stable
Do you need top speed in a loop?NoYes
Is the code simple and short?OftenSometimes

Think of Execute like cooking one cup of tea for a guest. You do it, you serve it, done. Think of Compile like setting up a tea stall: you do the setup once, then serve hundreds of cups quickly. If a rule will run again and again, compile it first.

Choosing Execute or Compile

Start
Run once?
Execute
Compile

Steps

1

Start

You have an expression

2

Run once?

Will it run a single time?

3

Execute

Yes: keep it simple

4

Compile

No: build a delegate and reuse

A quick decision path for picking the right method.

Real-life uses

Why would you ever want this? Here are everyday reasons that show up in real apps.

  • Email templates with placeholders. A marketing team writes Hello FirstName, your order Total is ready. The values fill in at runtime. No code change needed for new templates.
  • Dynamic filters for Entity Framework. A user builds a search with chosen fields. You turn their choices into a filter expression at runtime.
  • Business rules that change often. Discount rules, tax rules, or bonus points can live in a database. Business folks tweak them without waiting for a new release.
  • Spreadsheet-style formulas. Let users type a formula like Price * Quantity * 0.9 and compute the result.

The thread tying these together is the same: the rule is not known when you build the app. It is decided later, by data or by a person.

A short safety talk (please read this)

Running code from a string is powerful, and power needs care. If the string comes from a user you do not trust, they could try to run code that hurts your system. This is a real risk, not a small one.

Keep these habits.

  • Only run code you trust. Code written by your own team or stored safely is fine.
  • Never paste raw user input straight into Execute. If users must supply formulas, keep the allowed shapes tight and simple.
  • Treat dynamic code like an open door. Lock it unless you have a good reason to leave it open.
Trusted code is safe to run. Untrusted input needs checks first.

Handling errors gracefully

When the code in your string is wrong, the library throws an exception, just like a normal compile error would, but at runtime. Wrap risky calls in a try/catch so one bad expression does not crash your whole app.

using Z.Expressions;
 
try
{
    // This expression has a mistake on purpose
    var value = Eval.Execute<int>("X + ");
    Console.WriteLine(value);
}
catch (Exception ex)
{
    // Tell the user kindly instead of crashing
    Console.WriteLine("That formula could not run: " + ex.Message);
}

This matters most when the expression comes from outside your code, such as a config file someone edited by hand. A small typo should give a friendly message, not a broken page.

Tips for using it well

A few small habits make this library pleasant to work with over time.

  • Name your parameters clearly. Total and Quantity read better than a and b inside an expression string.
  • Compile and store delegates you reuse. Keep them in a field or a cache so you build each one only once.
  • Keep expressions short. Remember the free limit is 50 characters. Short expressions are also easier to read and test.
  • Log what you run. When a dynamic rule misbehaves, a log of the exact expression saves hours of guessing.

Putting it all together

Let us end with one tiny scene. Suppose your shop gives a discount that changes during festivals. Instead of editing code each time, you store the rule as text.

using Z.Expressions;
 
// This rule could come from a database row
string discountRule = "Price - (Price * Percent / 100)";
 
// Compile once because we will use it for every customer today
var applyDiscount = Eval.Compile<Func<decimal, decimal, decimal>>(
    discountRule,
    "Price", "Percent"
);
 
decimal finalPrice = applyDiscount(500m, 10m);
Console.WriteLine(finalPrice); // 450

When the festival ends, you change one row in the database. The shop keeps running. That is the chalkboard, not the printed price list.

References and further reading

Quick recap

  • Dynamic code execution means running C# written as a string while your program is already running.
  • The C# Eval Expression library (Z.Expressions.Eval) makes this easy and understands math, strings, LINQ, and your own classes.
  • Eval.Execute runs an expression once. Pass values with an anonymous object, a class, a dictionary, or an ExpandoObject.
  • Eval.Compile reads an expression once and returns a fast delegate, ideal when you run the same rule many times.
  • Pick Execute for one-off runs and Compile for repeated runs in loops.
  • The library is free up to 50 characters; longer expressions need a license.
  • Be careful with untrusted input and wrap calls in try/catch so a bad formula never crashes your app.

Related Posts