私のコメントで述べたように、列挙型を文字列として格納することが絶対的な要件でない限り、[Flags]
属性を使用して列挙型を設定し、列挙型を int として格納する規則を作成することをお勧めします。これが私が使用するものです(FluentNHを使用していることに注意してください):
コンベンション
public class EnumConvention : IUserTypeConvention
{
public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
{
// You can use this if you don't want to support nullable enums
// criteria.Expect(x => x.Property.PropertyType.IsEnum);
criteria.Expect(x => x.Property.PropertyType.IsEnum ||
(x.Property.PropertyType.IsGenericType &&
x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) &&
x.Property.PropertyType.GetGenericArguments()[0].IsEnum)
);
}
public void Apply(IPropertyInstance target)
{
target.CustomType(target.Property.PropertyType);
}
}
ビット
ごとの比較が機能し続けるためには、値の設定に注意する必要があることに注意してください。
// Note I use long to support enough enum values
[Flags]
public enum MyEnum : long
{
Foo = 1,
Bar = 1 << 1,
Baz = 1 << 2
}
それ以上のことはしなくてもいいと思います。設定または取得を繰り返す必要はありません。HasFlag()
値の存在をテストするには、列挙型で拡張メソッドを使用できます。
アップデート
この種の列挙型をサポートするように MvcGrabBag コードを変更するには、GetItemsFromEnum
次のようにメソッドを変更する必要があります。
public static IEnumerable<SelectListItem> GetItemsFromEnum<T>(T enumeration = default(T)) where T : struct
{
FieldInfo[] fields = enumeration.GetType().GetFields(BindingFlags.Public | BindingFlags.Static);
return from field in fields
let value = Enum.Parse(enumeration.GetType(), field.Name)
let descriptionAttributes = field.GetCustomAttributes(typeof(DescriptionAttribute), true)
select new SelectListItem
{
Text = descriptionAttributes.Length > 0
? ((DescriptionAttribute)descriptionAttributes[0]).Description
: field.Name,
Value = Convert.ToInt64(value).ToString(),
Selected = (Convert.ToInt64(enumeration) & Convert.ToInt64(value)) == Convert.ToInt64(value)
};
}
そのツールキットの他のどの側面がその署名に依存しているかがわからないという理由だけで、私はそれをジェネリックとして保持していることに注意してください。ただし、必要ではないことがわかります。を削除し<T>
て、署名を次のようpublic static IEnumerable<SelectListItem> GetItemsFromEnum(Enum enumeration)
にすると、正常に機能します。
このコードは、Description
属性から派生した名前をサポートするという私の規則を使用していることにも注意してください。これを使用して、ラベルをより人間が読めるようにします。列挙型は次のようになります。
[Flags]
public enum MyEnum : long
{
[Description("Super duper foo")]
Foo = 1,
[Description("Super duper bar")]
Bar = 1 << 1,
// With no description attribute it will use the ToString value
Baz = 1 << 2
}