How to Resolve Error "CS0226: An '__arglist' expression may only appear inside of a call or new expression" in C#
The Compiler Error CS0226 is a syntax error related to the undocumented legacy keyword __arglist. The message reads: "An __arglist expression may only appear inside of a call or new expression".
The __arglist keyword provides access to the C-style variable argument lists (varargs), primarily for Interoperability (P/Invoke) with unmanaged code like C++ methods. Because it interacts directly with the calling convention of a method, it is only valid inside the parentheses of a method invocation or a constructor call. You cannot use it as a standalone variable, return value, or in other expressions.
This guide explains how to correctly use this rare feature when interacting with unmanaged libraries.
Understanding __arglist
In standard C#, we use the params keyword for variable arguments. However, params creates a C# array. C-style functions (like printf in msvcrt.dll) do not understand C# arrays; they expect arguments pushed onto the stack in a specific way.
- Definition:
void MyMethod(__arglist)indicates the method accepts varargs. - Usage:
MyMethod(__arglist(x, y, z))indicates you are passing varargs.
The syntax __arglist(...) constructs a special RuntimeArgumentHandle. This construction is only valid at the exact moment of calling the function.
Scenario: Incorrect Usage of __arglist
This error occurs when you try to treat the result of __arglist(...) as if it were a regular object or variable that can be stored.
Example of Trying to assign the argument list to a variable before passing it.
public class Interop
{
// Method defined to accept __arglist
public static void NativeLog(__arglist)
{
}
public static void Run()
{
int x = 5;
int y = 10;
// ⛔️ Error CS0226: An __arglist expression may only appear
// inside of a call or new expression.
// You cannot "save" the arglist creation to a variable.
var args = __arglist(x, y);
NativeLog(args); // This would be invalid
}
}
Solution: Moving __arglist into the Call
You must inline the __arglist expression directly into the method call parentheses.
Solution
public class Interop
{
public static void NativeLog(__arglist)
{
// Implementation usually involves ArgIterator
ArgIterator iterator = new ArgIterator(__arglist);
}
public static void Run()
{
int x = 5;
int y = 10;
// ✅ Correct: __arglist is used directly inside the function call
NativeLog(__arglist(x, y));
}
}
Example: Calling printf (P/Invoke)
The most common real-world use case is calling standard C library functions.
using System.Runtime.InteropServices;
class Program
{
// Define the extern method with __arglist
[DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int printf(string format, __arglist);
static void Main()
{
// ✅ Correct usage
printf("Val: %d, Str: %s\n", __arglist(123, "Hello"));
}
}
Conclusion
CS0226 enforces the transient nature of the __arglist structure.
- Usage Restriction: You cannot assign
__arglist(...)to a variable (var x = ...). - Usage Restriction: You cannot return
__arglist(...)from a method. - Correct Syntax: Always type it directly inside the call:
Method(__arglist(a, b)).