当T为什么时,为什么Nullable <T>不是有效的自定义属性参数?

Mik*_*Two 25 c# attributes nullable

如果我有这样的枚举

public enum Hungry
{
    Somewhat,
    Very,
    CouldEatMySocks
}
Run Code Online (Sandbox Code Playgroud)

和这样的自定义属性

public class HungerAttribute : Attribute
{
    public Hungry HungerLevel { get; set; }
    public Hungry? NullableHungerLevel { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我可以做这个

[Hunger(HungerLevel = Hungry.CouldEatMySocks)]
public class Thing1
Run Code Online (Sandbox Code Playgroud)

但我不能这样做

[Hunger(NullableHungerLevel = Hungry.CouldEatMySocks)]
public class Thing2
Run Code Online (Sandbox Code Playgroud)

它会生成一个错误,指出"'NullableHungerLevel'不是有效的命名属性参数,因为它不是有效的属性参数类型".

为什么不允许这样做?据我所知,从根本上说它不在可接受的类型列表中.有效类型似乎是基元,枚举,字符串,类型和前面类型的一维数组.

这只是一个旧规则,当Nullable出现时没有得到更新?

Lar*_*ard 28

Hungry?等于Nullable<Hungry>,就其而言

[Hunger(NullableHungerLevel = Hungry.CouldEatMySocks)]
Run Code Online (Sandbox Code Playgroud)

等于

[Hunger(NullableHungerLevel = new Nullable<Hungry>(Hungry.CouldEatMySocks))]
Run Code Online (Sandbox Code Playgroud)

由于您只能在命名属性参数中使用常量值,因此您必须使用Shimmy的解决方案.


Shi*_*mmy 22

要解决此问题,请在属性中创建另一个初始值设定项:

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 }
}
Run Code Online (Sandbox Code Playgroud)

我知道你不会同时使用这两个属性.

  • @Shimmy谢谢你留下这个答案. (7认同)
  • @Shimmy.就个人而言,我会留下答案.它指出了在这种情况下正确的方法.如果其他人搜索该错误,那仍然有用.它仍然有助于对话.如果您决定删除它,请将有关如何解决问题的建议移至评论. (6认同)

cod*_*nix 7

属性可以仅具有参数基元,类型表达式和数组创建表达式.

Nullable是一个结构.

因此不允许那里.

我怀疑汇编文件格式本身不允许在存储属性值的位置存储复杂类型,如结构.

我不知道有任何改变它的计划.但我无法解释为什么存在这种限制.