C#idiomatic C#
delegate-operatorcsharp/language-reference/operators

Language

delegate operator

The C# delegate operator that is used to create anonymous methods. These types can be used for `Func<>` and `Action<>` parameters in many .NET APIs.

  • page csharp/language-reference/operators/delegate-operator
  • updated 01/20/2026

The delegate operator creates an anonymous method that you can convert to a delegate type.


ms.custom: "updateeachrelease"

The C# language reference documents the most recently released version of the C# language. It also contains initial documentation for features in public previews for the upcoming language release.

The documentation identifies any feature first introduced in the last three versions of the language or in current public previews.

You can convert an anonymous method to types such as System.Action and System.Func. Many methods use these types as arguments.

sample · csharpdocs/csharp/language-reference/operators/snippets/shared/DelegateOperator.csAnonymousMethod

csharp
namespace operators;

public static class DelegateOperator
{
    public static void Examples()
    {
        AnonymousMethod();
        Lambda();
        WithoutParameterList();
        Discards();
        Static();
    }

    private static void AnonymousMethod()
    {
        // <SnippetAnonymousMethod>
        Func<int, int, int> sum = delegate (int a, int b) { return a + b; };
        Console.WriteLine(sum(3, 4));  // output: 7
        // </SnippetAnonymousMethod>
    }

    private static void Lambda()
    {
        // <SnippetLambda>
        Func<int, int, int> sum = (a, b) => a + b;
        Console.WriteLine(sum(3, 4));  // output: 7
        // </SnippetLambda>
    }

    private static void WithoutParameterList()
    {
        // <SnippetWithoutParameterList>
        Action greet = delegate { Console.WriteLine("Hello!"); };
        greet();

        Action<int, double> introduce = delegate { Console.WriteLine("This is world!"); };
        introduce(42, 2.7);

        // Output:
        // Hello!
        // This is world!
        // </SnippetWithoutParameterList>
    }

    private static void Discards()
    {
        // <SnippetDiscards>
        Func<int, int, int> constant = delegate (int _, int _) { return 42; };
        Console.WriteLine(constant(3, 4));  // output: 42
        // </SnippetDiscards>
    }

    private static void Static()
    {
        // <SnippetStatic>
        Func<int, int, int> sum = static delegate (int a, int b) { return a + b; };
        Console.WriteLine(sum(10, 4));  // output: 14
        // </SnippetStatic>
    }
}

When you use the delegate operator, you can omit the parameter list. If you omit the parameter list, you create an anonymous method that you can convert to a delegate type with any list of parameters, as the following example shows:

sample · csharpdocs/csharp/language-reference/operators/snippets/shared/DelegateOperator.csWithoutParameterList

csharp
namespace operators;

public static class DelegateOperator
{
    public static void Examples()
    {
        AnonymousMethod();
        Lambda();
        WithoutParameterList();
        Discards();
        Static();
    }

    private static void AnonymousMethod()
    {
        // <SnippetAnonymousMethod>
        Func<int, int, int> sum = delegate (int a, int b) { return a + b; };
        Console.WriteLine(sum(3, 4));  // output: 7
        // </SnippetAnonymousMethod>
    }

    private static void Lambda()
    {
        // <SnippetLambda>
        Func<int, int, int> sum = (a, b) => a + b;
        Console.WriteLine(sum(3, 4));  // output: 7
        // </SnippetLambda>
    }

    private static void WithoutParameterList()
    {
        // <SnippetWithoutParameterList>
        Action greet = delegate { Console.WriteLine("Hello!"); };
        greet();

        Action<int, double> introduce = delegate { Console.WriteLine("This is world!"); };
        introduce(42, 2.7);

        // Output:
        // Hello!
        // This is world!
        // </SnippetWithoutParameterList>
    }

    private static void Discards()
    {
        // <SnippetDiscards>
        Func<int, int, int> constant = delegate (int _, int _) { return 42; };
        Console.WriteLine(constant(3, 4));  // output: 42
        // </SnippetDiscards>
    }

    private static void Static()
    {
        // <SnippetStatic>
        Func<int, int, int> sum = static delegate (int a, int b) { return a + b; };
        Console.WriteLine(sum(10, 4));  // output: 14
        // </SnippetStatic>
    }
}

This functionality is the only feature of anonymous methods that lambda expressions don't support. In all other cases, use a lambda expression to write inline code. You can use discards to specify two or more input parameters of an anonymous method that the method doesn't use:

sample · csharpdocs/csharp/language-reference/operators/snippets/shared/DelegateOperator.csSnippetDiscards

csharp
namespace operators;

public static class DelegateOperator
{
    public static void Examples()
    {
        AnonymousMethod();
        Lambda();
        WithoutParameterList();
        Discards();
        Static();
    }

    private static void AnonymousMethod()
    {
        // <SnippetAnonymousMethod>
        Func<int, int, int> sum = delegate (int a, int b) { return a + b; };
        Console.WriteLine(sum(3, 4));  // output: 7
        // </SnippetAnonymousMethod>
    }

    private static void Lambda()
    {
        // <SnippetLambda>
        Func<int, int, int> sum = (a, b) => a + b;
        Console.WriteLine(sum(3, 4));  // output: 7
        // </SnippetLambda>
    }

    private static void WithoutParameterList()
    {
        // <SnippetWithoutParameterList>
        Action greet = delegate { Console.WriteLine("Hello!"); };
        greet();

        Action<int, double> introduce = delegate { Console.WriteLine("This is world!"); };
        introduce(42, 2.7);

        // Output:
        // Hello!
        // This is world!
        // </SnippetWithoutParameterList>
    }

    private static void Discards()
    {
        // <SnippetDiscards>
        Func<int, int, int> constant = delegate (int _, int _) { return 42; };
        Console.WriteLine(constant(3, 4));  // output: 42
        // </SnippetDiscards>
    }

    private static void Static()
    {
        // <SnippetStatic>
        Func<int, int, int> sum = static delegate (int a, int b) { return a + b; };
        Console.WriteLine(sum(10, 4));  // output: 14
        // </SnippetStatic>
    }
}

For backwards compatibility, if only a single parameter is named _, the compiler treats _ as the name of that parameter within an anonymous method.

Use the static modifier when you declare an anonymous method:

sample · csharpdocs/csharp/language-reference/operators/snippets/shared/DelegateOperator.csSnippetStatic

csharp
namespace operators;

public static class DelegateOperator
{
    public static void Examples()
    {
        AnonymousMethod();
        Lambda();
        WithoutParameterList();
        Discards();
        Static();
    }

    private static void AnonymousMethod()
    {
        // <SnippetAnonymousMethod>
        Func<int, int, int> sum = delegate (int a, int b) { return a + b; };
        Console.WriteLine(sum(3, 4));  // output: 7
        // </SnippetAnonymousMethod>
    }

    private static void Lambda()
    {
        // <SnippetLambda>
        Func<int, int, int> sum = (a, b) => a + b;
        Console.WriteLine(sum(3, 4));  // output: 7
        // </SnippetLambda>
    }

    private static void WithoutParameterList()
    {
        // <SnippetWithoutParameterList>
        Action greet = delegate { Console.WriteLine("Hello!"); };
        greet();

        Action<int, double> introduce = delegate { Console.WriteLine("This is world!"); };
        introduce(42, 2.7);

        // Output:
        // Hello!
        // This is world!
        // </SnippetWithoutParameterList>
    }

    private static void Discards()
    {
        // <SnippetDiscards>
        Func<int, int, int> constant = delegate (int _, int _) { return 42; };
        Console.WriteLine(constant(3, 4));  // output: 42
        // </SnippetDiscards>
    }

    private static void Static()
    {
        // <SnippetStatic>
        Func<int, int, int> sum = static delegate (int a, int b) { return a + b; };
        Console.WriteLine(sum(10, 4));  // output: 14
        // </SnippetStatic>
    }
}

A static anonymous method can't capture local variables or instance state from enclosing scopes.

Use the delegate keyword to declare a delegate type.

The compiler can cache the delegate object that it creates from a method group. Consider the following method:

csharp
static void StaticFunction() { }

When you assign the method group to a delegate, the compiler caches the delegate:

csharp
Action a = StaticFunction;

C# language specification

For more information, see the Anonymous function expressions section of the C# language specification.

See also