Anonymous Methods
Vaibhav • September 11, 2025
In the last few articles, we explored how delegates allow methods to be passed around like variables, and how multicast delegates can invoke multiple methods in sequence. Now we’re ready to introduce a powerful and expressive feature that builds on delegates: anonymous methods. These are methods without a name - defined inline, right where you need them.
Anonymous methods are especially useful when you want to pass short bits of logic to a delegate, without cluttering your code with separate method declarations. They’re a stepping stone to lambda expressions, and they help you write concise, readable code in scenarios like filtering, event handling, and callbacks.
What is an Anonymous Method?
An anonymous method is a method that doesn’t have a name. Instead of declaring it separately, you define it
inline using the delegate
keyword. It’s assigned directly to a delegate
variable, and behaves just like any other method - it can take parameters, return values, and access variables
in scope.
public delegate void Logger(string message);
Logger log = delegate(string msg)
{
Console.WriteLine("Log: " + msg);
};
log("System started"); // Output: Log: System started
In this example, we define a method inline using delegate(string msg)
. It
matches the Logger
delegate’s signature, so it can be assigned directly. When
log
is invoked, the anonymous method runs.
Why Use Anonymous Methods?
Anonymous methods are ideal when the logic is short, used only once, and doesn’t need a name. They reduce boilerplate and keep related code together. For example, when filtering a list or handling a button click, you often want to define the behavior right where it’s used.
They also allow you to capture variables from the surrounding scope - a concept known as closure. This makes them powerful for customizing behavior based on context.
Anonymous methods were introduced in C# 2.0. They paved the way for lambda expressions, which we’ll explore in the next article.
Syntax and Structure
The syntax for an anonymous method uses the delegate
keyword followed by a
parameter list and a method body. You don’t specify a return type - the compiler infers it from the body.
delegate(parameters)
{
// method body
}
You can assign this to any delegate type that matches the signature. For example:
public delegate int Calculator(int x, int y);
Calculator calc = delegate(int a, int b)
{
return a + b;
};
Console.WriteLine(calc(2, 3)); // Output: 5
The anonymous method matches the Calculator
delegate’s signature, so it can be
assigned directly. When calc
is invoked, the method runs and returns the
result.
Anonymous Methods Without Parameters
If your delegate doesn’t take parameters, you can omit the parentheses entirely. This makes the syntax even cleaner.
public delegate void Notifier();
Notifier notify = delegate
{
Console.WriteLine("Notification triggered");
};
notify(); // Output: Notification triggered
This is useful for simple callbacks or event handlers that don’t need input. The method body runs when the delegate is invoked.
Capturing Variables from Outer Scope
One of the most powerful features of anonymous methods is their ability to capture variables from the surrounding scope. This is called a closure. The anonymous method keeps a reference to the captured variable, even if the original context is gone.
int counter = 0;
Notifier notify = delegate
{
counter++;
Console.WriteLine("Counter: " + counter);
};
notify(); // Output: Counter: 1
notify(); // Output: Counter: 2
The anonymous method captures the counter
variable. Each time it’s invoked, it
increments and prints the value. This behavior is essential for building stateful callbacks and dynamic
behavior.
Captured variables are stored in a hidden class created by the compiler. This allows the anonymous method to maintain state across invocations.
Using Anonymous Methods in Collections
Anonymous methods are often used with collections - for filtering, transforming, or iterating. For example, you
can use them with List<T>
methods like Find
or ForEach
.
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
int even = numbers.Find(delegate(int n)
{
return n % 2 == 0;
});
Console.WriteLine(even); // Output: 2
Here, we use an anonymous method to define the condition for finding an even number. The method is passed
directly to Find
, keeping the logic close to the usage.
Anonymous Methods in Events
Anonymous methods are perfect for event handlers - especially when the logic is short and specific to the event.
You can attach them directly to an event using +=
.
public event Logger OnLog;
OnLog += delegate(string msg)
{
Console.WriteLine("Event: " + msg);
};
OnLog?.Invoke("User logged in"); // Output: Event: User logged in
This pattern is common in UI frameworks and reactive systems. It avoids cluttering your code with separate handler methods.
Use anonymous methods for short-lived event handlers. For reusable or complex logic, prefer named methods for clarity and maintainability.
Limitations of Anonymous Methods
While anonymous methods are powerful, they have some limitations. You can’t use unsafe code inside them, and you
can’t specify parameter modifiers like ref
or out
. Also, they can’t be reused - once defined, they’re tied to the delegate
instance.
For more advanced scenarios, lambda expressions offer a more flexible and expressive syntax. We’ll explore those next.
Anonymous Methods vs Named Methods
You might wonder - when should I use an anonymous method, and when should I define a named method? The answer depends on context. Use anonymous methods when:
- The logic is short and used only once
- You want to keep related code together
- You need to capture variables from outer scope
Use named methods when:
- The logic is reused in multiple places
- You want to document or test the method separately
- The method is part of a public API or interface
Both approaches are valid - choose the one that makes your code clearer and easier to maintain.
Performance Considerations
Anonymous methods are compiled into regular methods behind the scenes. They’re efficient and optimized by the runtime. However, captured variables may introduce hidden allocations - especially if the method is stored long-term or used in tight loops.
If performance is critical, profile your code and consider using named methods or avoiding closures.
Note: Anonymous methods are safe and efficient for most scenarios. Just be mindful of captured variables and lifetime.
Summary
Anonymous methods allow you to define inline logic without declaring a separate method. They’re assigned directly to delegates, and they support parameters, return values, and variable capture. You learned how to use them for callbacks, event handlers, and collection operations - and how they compare to named methods.
Anonymous methods make your code more expressive and concise. They’re a key part of functional programming in C#, and they prepare you for the next step: lambda expressions, which offer even more elegant syntax and power.