Nullable< T>はなぜですか? Tが有効なカスタム属性パラメーターではない?

StackOverflow https://stackoverflow.com/questions/1416126

  •  06-07-2019
  •  | 
  •  

質問

このような列挙型がある場合

public enum Hungry
{
    Somewhat,
    Very,
    CouldEatMySocks
}

およびこのようなカスタム属性

public class HungerAttribute : Attribute
{
    public Hungry HungerLevel { get; set; }
    public Hungry? NullableHungerLevel { get; set; }
}

これを行うことができます

[Hunger(HungerLevel = Hungry.CouldEatMySocks)]
public class Thing1

しかしこれはできません

[Hunger(NullableHungerLevel = Hungry.CouldEatMySocks)]
public class Thing2

" 'NullableHungerLevel'は有効な名前付き属性引数ではないというエラーが生成されます。これは、有効な属性パラメータータイプではないためです。

なぜ許可されないのですか?基本的に、受け入れられるタイプのリストに載っていないことを理解しています。有効な型は、プリミティブ、列挙型、文字列、型、および前述の型の1次元配列のようです。

これは、Nullableが登場したときに更新されなかった古いルールですか?

役に立ちましたか?

解決

Hungry? Nullable< Hungry> と同じです。つまり、

[Hunger(NullableHungerLevel = Hungry.CouldEatMySocks)]

は等しい

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

名前付き属性引数では定数値しか使用できないため、Shimmyのソリューションに頼らなければなりません。

他のヒント

これを回避するには、属性に別の初期化子を作成します:

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

両方のプロパティを使用しないことを理解しています。

属性は、パラメータとしてプリミティブ、typeof式、および配列作成式のみを持つことができます。

Nullableは構造体です。

したがって、そこでは許可されていません。

アセンブリファイル形式自体では、属性値が格納される場所に構造体などの複雑な型を格納することはできません。

これを変更する予定はありません。しかし、この制限が存在する理由を説明することはできません。

null可能な列挙を作成する代わりに、その列挙のデフォルト値を作成できます。列挙型は最初の値からデフォルトを選択するため、このように列挙型を設定します

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

コードでこれを実行してnullをチェックできます

if(default(Hungry) == HungerLevel)//no value has been set
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top