Skip to main content

How to Resolve Error "CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type" in C#

The Compiler Error CS0182 is a restriction error related to Attribute Usage. The message reads: "An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type".

Attributes in C# ([MyAttribute]) are metadata that is compiled and stored directly in the assembly's header (metadata tables). Because this data must exist before the program ever runs, you cannot pass data to an attribute that is calculated at runtime. You can only pass values that the compiler can resolve to exact bytes at compile-time.

This guide explains exactly what constitutes a valid "constant expression" and how to fix arguments that violate this rule.

Understanding Valid Attribute Arguments

To fix CS0182, you must provide arguments that fit into one of these categories:

  • Literals: 10, "Hello", true, null.
  • Constants: Fields marked with const.
  • Enums: Explicit enumeration values (e.g., Color.Red).
  • Types: typeof(MyClass).
  • Arrays: 1-dimensional arrays created using only the items listed above (e.g., new[] { 1, 2 }).

You cannot use:

  • Variables (even static ones).
  • static readonly fields.
  • Method calls (e.g., int.Parse("5")).
  • Properties (e.g., DateTime.Now).
  • new object instantiation (except for arrays).

Scenario 1: Passing Variables or Readonly Fields

This is the most common mistake. You want to share a string between your logic code and your attribute, so you define a static string. However, standard static fields are initialized at runtime, making them invalid for attributes.

Example of error

public class ApiConfig
{
// ⚠️ 'static readonly' is evaluated at Runtime.
public static readonly string RouteName = "api/v1";
}

[AttributeUsage(AttributeTargets.Class)]
public class RouteAttribute : Attribute
{
public RouteAttribute(string path) { }
}

// ⛔️ Error CS0182: An attribute argument must be a constant expression...
// The compiler cannot bake the value of 'RouteName' into the metadata.
[Route(ApiConfig.RouteName)]
public class MyController
{
}

Solution: Use const

Change the field to const. Constants are substituted with their literal value during compilation.

public class ApiConfig
{
// ✅ Correct: 'const' is evaluated at Compile-Time.
public const string RouteName = "api/v1";
}

// ✅ Correct: Valid usage
[Route(ApiConfig.RouteName)]
public class MyController
{
}
tip

Pro Tip: You can also use the nameof() operator. Since nameof(MyClass) resolves to a string constant at compile-time, it is valid in attributes: [Route(nameof(MyController))].

Scenario 2: Using Method Calls or Properties

You might try to perform a calculation or call a helper method inside the attribute constructor. Even if the method returns a simple string, the compiler cannot execute that method while building the DLL.

Example of error

public class Utils
{
public static string GetVersion() => "1.0";
}

public class InfoAttribute : Attribute
{
public InfoAttribute(string version) { }
}

// ⛔️ Error CS0182: Cannot call methods inside an attribute argument.
[Info(Utils.GetVersion())]
public class App { }

// ⛔️ Error CS0182: Cannot use properties like DateTime.Now
[Info(DateTime.Now.ToString())]
public class TimeLog { }

Solution: Hardcode or Compute Internally

You must pass the raw data to the attribute and let the attribute (or the code reading the attribute) perform the logic later.

// ✅ Correct: Pass the literal string
[Info("1.0")]
public class App { }

If you need dynamic behavior (like "Current Time"), you cannot put it in the attribute arguments. Instead, put a placeholder in the attribute and resolve it at runtime via Reflection.

[Info("UseCurrentTime")] // Pass a flag or constant key
public class TimeLog { }

Scenario 3: Arrays with Dynamic Content

You can pass arrays to attributes, but every element inside the array initializer must also be a constant.

Example of error

public class Permissions
{
public static string AdminRole = "Admin"; // Not const
}

public class AuthorizeAttribute : Attribute
{
public AuthorizeAttribute(string[] roles) { }
}

// ⛔️ Error CS0182: The array creation is valid,
// but the element 'AdminRole' is not a constant.
[Authorize(new string[] { Permissions.AdminRole, "Guest" })]
public class AdminPanel { }

Solution: Ensure Elements are Constants

Make sure every variable inside the curly braces { ... } is a const.

public class Permissions
{
// ✅ Correct: Converted to const
public const string AdminRole = "Admin";
}

// ✅ Correct: All array elements are compile-time constants
[Authorize(new string[] { Permissions.AdminRole, "Guest" })]
public class AdminPanel { }

Conclusion

CS0182 ensures that the metadata baked into your compiled code is static and deterministic.

  1. Check Modifiers: Ensure any variables passed to attributes are marked const.
  2. Check Data: Ensure you aren't calling methods (GetId()) or properties (DateTime.Now).
  3. Check Arrays: Ensure arrays only contain literals or constants.