How to Resolve Error "CS0655: Not a valid named attribute argument because it is not a valid attribute parameter type" in C#
The Compiler Error CS0655 is a restriction error regarding Attribute usage. The message reads: " 'Name' is not a valid named attribute argument because it is not a valid attribute parameter type".
In C#, attributes are metadata serialized into the compiled binary (assembly). Because they must be "baked in" at compile-time, the Common Language Runtime (CLR) restricts the types of data you can pass to an attribute. You can only pass values that are compile-time constants and are supported by the attribute serialization format. This error occurs when you define a property in an attribute class using an unsupported type (like decimal, DateTime, or Guid) and try to assign a value to it using a named argument.
This guide lists the allowed types and demonstrates workarounds for unsupported types.
Understanding Valid Attribute Types
The CLR restricts attribute parameters (both constructor arguments and named properties) to a specific subset of types.
Allowed Types:
- Primitives:
bool,byte,char,short,int,long,float,double(and their unsigned counterparts). - Strings:
string. - Types:
System.Type. - Enums: Any public enum.
- Arrays: Single-dimensional arrays of the types above.
- Object: Provided the actual value assigned is one of the types above.
NOT Allowed (Common Triggers for CS0655):
decimal(Not a primitive in the CLR).DateTime.Guid.- Any custom Class or Struct.
Scenario 1: The decimal Restriction
This is the most common cause. While decimal is a built-in C# type, it is not a primitive type in the CLR metadata format. Therefore, you cannot use it as a named argument in an attribute.
Example of error
Defining an attribute with a decimal property and trying to set it.
using System;
public class ProductAttribute : Attribute
{
// It is legal to define this property inside the class...
public decimal Price { get; set; }
}
// ⛔️ Error CS0655: 'Price' is not a valid named attribute argument
// because it is not a valid attribute parameter type.
[Product(Price = 19.99m)]
public class Laptop
{
}
Solution: Use Double or String
You must change the underlying type of the property in the attribute class. Use double if floating-point precision is acceptable for metadata, or string if exact precision is required (and parse it later).
using System;
public class ProductAttribute : Attribute
{
// ✅ Correct: Change the backing store to a supported type (double)
public double Price { get; set; }
}
[Product(Price = 19.99)]
public class Laptop
{
}
If you stick with double, remember that 19.99 might be stored as 19.98999.... If exact financial precision is needed in the metadata, store it as a string ("19.99") and use decimal.Parse() in your reflection code.
Scenario 2: Using DateTime or Guid
Dates and Guids are complex structures that cannot be serialized into the attribute metadata format directly.
Example of error
using System;
public class HistoryAttribute : Attribute
{
public DateTime ModifiedDate { get; set; }
public Guid UniqueId { get; set; }
}
// ⛔️ Error CS0655: Neither DateTime nor Guid can be passed as named arguments.
[History(ModifiedDate = DateTime.Now, UniqueId = new Guid("..."))]
public class User
{
}
Solution: Pass Strings
Convert the values to strings.
using System;
public class HistoryAttribute : Attribute
{
// Storage strings
public string DateString { get; set; }
public string GuidString { get; set; }
// Helper properties to parse them (Logic resides here)
public DateTime GetDate() => DateTime.Parse(DateString);
public Guid GetId() => Guid.Parse(GuidString);
}
// ✅ Correct: Pass strings that can be parsed later.
[History(DateString = "2023-10-01", GuidString = "d22c100c-9c9b-4395-9272-c5d956555555")]
public class User
{
}
Conclusion
CS0655 is a limitation of the .NET metadata format.
- Check the Type: Are you trying to assign a
decimal,DateTime,Guid, or custom Class to an attribute property? - Use Primitives: Switch to
int,double,bool, orstring. - Parse Later: If you need a complex type, store it as a
stringin the attribute and parse it back into the complex type when you read the attribute via Reflection.