Skip to main content

How to Resolve Error "CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression" in C#

The Compiler Error CS0837 is a type-checking limitation. The message reads: "The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group."

In C#, the is and as operators are designed to check or convert the runtime type of an object. Lambda expressions (x => x + 1) and Method Groups (Console.WriteLine) do not have a fixed type until they are cast to a specific Delegate or Expression Tree. Because they are "typeless" until assigned, the compiler cannot check if a raw lambda "is" a specific type, nor can it cast it using "as".

This guide explains how to convert lambdas effectively so they can be type-checked.

Understanding Lambdas and Types

A lambda expression like () => 5 is amorphous.

  • It could be a Func<int>.
  • It could be an Expression<Func<int>>.
  • It could be a custom delegate MyDelegate.

The is and as operators work on objects that already have a type. Since the compiler doesn't know which delegate type the lambda represents yet, it refuses to perform the operation.

Scenario 1: Using is with Lambdas

This often happens when checking if a piece of logic matches a certain delegate signature (which is conceptually impossible in C# anyway, as delegates are structural).

Example of error

using System;

public class Program
{
static void Main()
{
// ⛔️ Error CS0837: The first operand of an 'is' operator may not be a lambda...
// The compiler asks: "What is the type of '() => 42'?" It doesn't have one yet.
if (() => 42 is Func<int>)
{
Console.WriteLine("It is a Func!");
}
}
}

Solution: Cast First

You must cast the lambda to a specific delegate type to give it a concrete identity. Once it is a delegate object, you can check it (though checking if a Func<int> is a Func<int> is redundant).

using System;

public class Program
{
static void Main()
{
// ✅ Correct: Cast the lambda to an object or specific delegate first.
Func<int> myFunc = () => 42;

if (myFunc is Func<int>)
{
Console.WriteLine("It is a Func!");
}
}
}

Scenario 2: Using as with Lambdas

This scenario is more common. You want to pass a lambda to a method that accepts an object, so you try to convert it using as.

Example of error

using System;

public class Program
{
static void Run(object code) { }

static void Main()
{
// ⛔️ Error CS0837: Cannot use 'as' on a raw lambda.
Run((() => Console.WriteLine("Hi")) as Action);
}
}

Solution: Use a Cast (Type)

Unlike as (which can return null), a direct cast (Type) forces the compiler to interpret the lambda as that specific type immediately.

using System;

public class Program
{
static void Run(object code) { }

static void Main()
{
// ✅ Correct: Use a direct cast.
// This tells the compiler: "Treat this lambda as an Action delegate."
Run((Action)(() => Console.WriteLine("Hi")));
}
}

Conclusion

CS0837 prevents you from treating abstract code blocks as concrete objects.

  1. Avoid is: Checking if a lambda is a delegate is rarely useful. Assign it to a typed variable instead.
  2. Avoid as: Use Explicit Casting (Action)(() => ...) instead of ... as Action. Direct casting provides the necessary context for the compiler to generate the delegate.