The Compiler Error CS1016 is a syntax error regarding the usage of Attributes. The message reads: "Named attribute argument expected".
In C#, attributes can accept arguments in two ways:
- Positional Arguments: These map directly to the attribute class's constructor parameters.
- Named Arguments: These map to the public properties or fields of the attribute class.
The strict rule for attribute syntax is: All positional arguments must appear before any named arguments. Once you start assigning values to properties (e.g., Name = "Value"), you cannot go back to supplying constructor arguments. If the compiler encounters a value without a name after a named argument, it raises CS1016.
Understanding Attribute Argument Order
When you use an attribute like [MyAttribute(1, Prop = 2)]:
1is passed to the constructor.Prop = 2sets the propertyPropon the instance after creation.
The compiler parses the argument list from left to right.
- Phase 1: Collect arguments for the constructor.
- Phase 2: Once a named argument (
Prop = ...) is seen, switch to "Property Setting Mode".
If you try to pass a constructor argument during "Phase 2", the compiler doesn't know what to do with it because it is expecting another Name = Value pair.
Scenario: Mixing Positional and Named Arguments
This error typically happens when a developer remembers a parameter they forgot to add to the constructor, but adds it to the end of the list after optional property assignments.
Setup
Let's define a custom attribute with one constructor parameter (id) and one optional property (Role).
using System;
[AttributeUsage(AttributeTargets.Class)]
public class DeveloperAttribute : Attribute
{
// Named Argument (Property)
public string Role { get; set; }
// Positional Argument (Constructor)
public DeveloperAttribute(int id)
{
// ...
}
}Example of error
Attempting to put the id (101) after setting the Role.
// ⛔️ Error CS1016: Named attribute argument expected
// The compiler sees 'Role = "Backend"'. It expects all subsequent arguments
// to also be named (e.g., Level = 5).
// Instead, it found '101', which is a positional value.
[Developer(Role = "Backend", 101)]
public class MyService
{
}Solution: Reorder the Arguments
To fix this, simply move all constructor (positional) arguments to the beginning of the list.
Solution: move 101 to the front.
// ✅ Correct: Positional arguments come first.
// 1. Constructor(101) is called.
// 2. Property Role is set to "Backend".
[Developer(101, Role = "Backend")]
public class MyService
{
}Conclusion
CS1016 is a simple ordering rule.
- Identify the Syntax: Look at your attribute usage
[Attribute(...)]. - Check Order: Ensure that values appearing alone (e.g.,
"Value",123) appear before values with assignments (e.g.,Name = "Value"). - Refactor: Move standard arguments to the left, property assignments to the right.