Why decimal is not a valid attribute parameter type?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
In C#, attributes are stored as metadata, not as arbitrary runtime objects. That is why attribute constructor arguments and named property values are limited to a small set of types, and decimal is not one of them.
Why decimal Is Rejected
C# attributes compile into CLR custom attribute metadata. The metadata format supports only certain constant-like element types. Those include primitives such as int, bool, double, string, Type, enums, object, and one-dimensional arrays of supported types.
decimal is a built-in C# type, but it is not one of the attribute parameter types permitted by the metadata format. So this fails:
The compiler error is not saying decimal is unsupported in C# generally. It is saying decimal cannot be encoded as an attribute argument.
Why Other Constants Work
Primitive numeric types such as int and double are special here because the attribute system knows how to persist them directly into metadata.
This works:
The difference is not whether the value is constant in your source code. The difference is whether the CLR attribute metadata format supports the type.
Practical Workarounds
Use double If Approximation Is Acceptable
If the attribute value is descriptive rather than financially exact, double may be enough.
This is fine for ratios or heuristic thresholds. It is usually the wrong choice for currency.
Store The Value As A String
If precision matters, encode the value as a string and parse it inside the attribute.
This is the most common workaround when exact decimal semantics are required.
Store Minor Units As An Integer
If the meaning is currency, another robust option is to store minor units such as cents.
This avoids parsing and keeps the metadata representation simple.
Why C# Does Not Special-Case decimal
It is tempting to think the compiler could just serialize a decimal anyway. But attributes are part of a cross-language, runtime-level metadata system. C# does not get to invent new element types for custom attribute encoding without CLR support.
That distinction matters. The limitation belongs to the underlying metadata representation, not just to C# syntax rules.
Common Pitfalls
A common misconception is that const decimal should make decimal valid for attributes. It does not. Compile-time const-ness and valid attribute parameter types are different rules.
Another issue is using double as a quick replacement for financial data. That solves the compiler error but may introduce rounding behavior you explicitly wanted to avoid by choosing decimal in the first place.
Parsing strings inside attributes also needs care. Always use invariant formatting if the value is part of source code metadata. Otherwise, culture-specific parsing can become a hidden bug.
Finally, avoid overusing attributes for data that is not really metadata. If the value changes often or needs rich structure, a configuration file or regular code object may be the better design.
Summary
- '
decimalis not a valid attribute parameter type because CLR custom attribute metadata does not support it.' - The restriction is about metadata encoding, not about whether
decimalis a valid C# type. - Use
doubleonly when approximate numeric values are acceptable. - Use
stringor integer minor units when exact decimal semantics matter. - Attribute arguments are for simple metadata, so do not force complex data into them if a better design exists.

