Why is a Nullable not a valid Custom Attribute Parameter when T is?

前端 未结 4 2121
猫巷女王i
猫巷女王i 2020-12-30 22:07

If I have an enum like this

public enum Hungry
{
    Somewhat,
    Very,
    CouldEatMySocks
}

and a custom attribute like this

<         


        
相关标签:
4条回答
  • 2020-12-30 22:46

    Instead of creating nullable enum, you can create default value for that enum. Enum pick default from 1st value, so set your enum like this

    public enum Hungry
    {
        None,
        Somewhat,
        Very,
        CouldEatMySocks
    }
    

    in your code you could do this to check for null

    if(default(Hungry) == HungerLevel)//no value has been set
    
    0 讨论(0)
  • 2020-12-30 22:54

    Hungry? is equal to Nullable<Hungry>, which in terms mean that

    [Hunger(NullableHungerLevel = Hungry.CouldEatMySocks)]
    

    is equal to

    [Hunger(NullableHungerLevel = new Nullable<Hungry>(Hungry.CouldEatMySocks))]
    

    Since you can only use constant values in named attribute arguments you will have to resort to Shimmy's solution.

    0 讨论(0)
  • 2020-12-30 22:58

    Attributes may have as only parameters primitives, typeof expressions and array-creation expression.

    Nullable is a struct.

    Therefore it is not allowed there.

    I suspect the assembly file format itself doesn't allow storage of complex types like structs in the place where attribute values are stored.

    I don't know of any plans to change that. But I cannot explain why this restriction exist.

    0 讨论(0)
  • 2020-12-30 23:03

    To get around this create another initializer in your Attribute:

    class Program
    {
      [Hunger()]
      static void Main(string[] args)
      {
      }
    
      public sealed class HungerAttribute : Attribute
      {        
        public Hungry? HungerLevel { get; }
        public bool IsNull => !_HungerLevel.HasValue;
    
        public HungerAttribute()
        {
        }
    
        //Or:
        public HungerAttribute(Hungry level)
        {
          HungerLevel = level;
        }
      }
    
      public enum Hungry { Somewhat, Very, CouldEatMySocks }
    }
    

    I understand that you're not going to use both properties.

    0 讨论(0)
提交回复
热议问题