Problem
I have created a custom attribute class and I am trying to pass in a value. It looks like this:
public enum ComputerStatus
{
[BgColor(Color.Yellow)]
Unregistered,
[BgColor(Color.LightGreen)]
Registered,
[BgColor(Color.Red)]
PingFailed,
[BgColor(Color.Red)]
PortNotFound,
[BgColor(Color.LightGreen)]
FoundAndRegistered
}
Code language: C# (cs)
I’m getting the following error message:
Attribute constructor parameter has type Color which is not a valid attribute parameter type
I have also gotten this error message, which has the same underlying cause:
An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
Solution
You must specify a value which is considered constant during compile-time.
Here are examples of what types you can pass in:
public enum CustomAttributeParameterTester
{
[CustomAttributeValidParameters(typeof(MyClass))]
TypeOf,
[CustomAttributeValidParameters(1)]
IntegerLiteral,
[CustomAttributeValidParameters(Constants.ONE)]
IntegerConstant,
[CustomAttributeValidParameters("test string")]
StringLiteral,
[CustomAttributeValidParameters(1, 2, 3)]
ParamsArray,
[CustomAttributeValidParameters(new[] { true, false })]
Array,
[CustomAttributeValidParameters(TestEnum.Deployed)]
Enum
}
public class CustomAttributeValidParameters : Attribute
{
public CustomAttributeValidParameters(Type type)
{
}
public CustomAttributeValidParameters(int i)
{
}
public CustomAttributeValidParameters(string s)
{
}
public CustomAttributeValidParameters(params int[] args)
{
}
public CustomAttributeValidParameters(bool[] arr)
{
}
public CustomAttributeValidParameters(TestEnum testEnum)
{
}
}
public enum TestEnum
{
Init,
Tested,
Deployed
}
Code language: C# (cs)
How I solved it for my specific situation
In my case, instead of using System.Drawing.Color (which is a struct), I have to pass in System.Drawing.KnownColor, which is an enum (therefore a compile-time constant), and then map that to Color.
BgColorAttribute – my custom attribute
using System;
using System.Drawing;
namespace AttributeProblem
{
public class BgColorAttribute : Attribute
{
public Color Color { get; }
public BgColorAttribute(KnownColor c)
{
//Why use KnownColor? Because can't have Color, which is a struct, as the parameter to an attribute!
Color = Color.FromKnownColor(c);
}
}
}
Code language: C# (cs)
ComputerStatus – where I’m using the custom attribute
using System.Drawing;
namespace AttributeProblem
{
public enum ComputerStatus
{
[BgColor(KnownColor.Yellow)]
Unregistered,
[BgColor(KnownColor.LightGreen)]
Registered,
[BgColor(KnownColor.Red)]
PingFailed,
[BgColor(KnownColor.Red)]
PortNotFound,
[BgColor(KnownColor.LightGreen)]
FoundAndRegistered
}
}
Code language: C# (cs)