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