C# – Attribute constructor parameter is not a valid attribute parameter type

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 }

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(ITestInterface))] Interface, [CustomAttributeValidParameters(typeof(Test))] Class, [CustomAttributeValidParameters(1)] IntegerLiteral, [CustomAttributeValidParameters(CustomAttributeValidParameters.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 const int ONE = 1; public CustomAttributeValidParameters(Type interfaceType) { } 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 } public interface ITestInterface { } public class Test : ITestInterface { }

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); } } }

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 } }

Leave a Comment