【问题标题】:Enum.HasFlag is not working as expected [duplicate]Enum.HasFlag 未按预期工作[重复]
【发布时间】:2018-03-19 15:11:35
【问题描述】:

我有一个带有这样标志的枚举:

[Flags]
public enum ItemType
{
    Shop,
    Farm,
    Weapon,
    Process,
    Sale
}

然后我在列表中有几个对象设置了一些标志和一些未设置的标志。它看起来像这样:

public static List<ItemInfo> AllItems = new List<ItemInfo>
{
        new ItemInfo{ID = 1, ItemType = ItemType.Shop, Name = "Wasserflasche", usable = true, Thirst = 50, Hunger = 0, Weight = 0.50m, SalesPrice = 2.50m, PurchasePrice = 5,  ItemUseAnimation = new Animation("Trinken", "amb@world_human_drinking@coffee@female@idle_a", "idle_a", (AnimationFlags.OnlyAnimateUpperBody | AnimationFlags.AllowPlayerControl)) },
        new ItemInfo{ID = 2, ItemType = ItemType.Sale, Name = "Sandwich", usable = true, Thirst = 0, Hunger = 50, Weight = 0.5m, PurchasePrice = 10, SalesPrice = 5, ItemUseAnimation = new Animation("Essen", "mp_player_inteat@pnq", "intro", 0) },
        new ItemInfo{ID = 3, ItemType = (ItemType.Shop|ItemType.Process), Name = "Apfel", FarmType = FarmTypes.Apfel, usable = true, Thirst = 25, Hunger = 25, Weight = 0.5m, PurchasePrice = 5, SalesPrice = 2, ItemFarmAnimation = new Animation("Apfel", "amb@prop_human_movie_bulb@base","base", AnimationFlags.Loop)},
        new ItemInfo{ID = 4, ItemType = ItemType.Process, Name = "Brötchen", usable = true, Thirst = -10, Hunger = 40, Weight = 0.5m, PurchasePrice = 7.50m, SalesPrice = 4}
}

然后我循环遍历列表并询问是否设置了标志ItemType.Shop,如下所示:

List<ItemInfo> allShopItems = ItemInfo.AllItems.ToList();
foreach(ItemInfo i in allShopItems)
{
    if (i.ItemType.HasFlag(ItemType.Shop))
    {
        API.consoleOutput(i.Name);
    }
}

这是我的循环的输出 - 它显示了列表中的所有项目,在这种情况下,.HasFlag 方法总是返回 true。

Wasserflasche
Sandwich
Apfel
Brötchen

【问题讨论】:

  • 标志需要值是 2 的幂,例如1, 2, 4, 8, 16唯一 Flags 属性所做的事情是更改枚举序列化为字符串的方式。
  • 不像你想象的那样工作。
  • 您的 Brötchen G 发现了一个语法高亮错误
  • 该死的谢谢,它现在可以工作了:D
  • 你有一个有趣的枚举,其中一些东西可以同时是 ShopWeaponSaleItemType 可能不是它的最佳名称,否则您并不真正想要枚举。

标签: c# enums flags


【解决方案1】:

尝试为你的枚举赋值

[Flags]
public enum ItemType 
{
    Shop = 1,
    Farm = 2,
    Weapon = 4,
    Process = 8,
    Sale = 16
}

这里有 一些 Guidelines for FlagsAttribute and Enum(摘自 Microsoft Docs)

  • 仅当要对数值执行按位运算(AND、OR、EXCLUSIVE OR)时,才对枚举使用 FlagsAttribute 自定义属性。
  • 以 2 的幂定义枚举常数,即 1、2、4、8 等。这意味着组合枚举常量中的各个标志不重叠。

【讨论】:

  • 您不应使用0 作为标志枚举。此外,您有重复的 2 值。
  • 将标志枚举与 None 以外的任何选项作为等于 0 的选项几乎总是一个糟糕的计划。
  • 考虑将Shop = 0 更改为None = 0
  • 感谢您的提示。在此页面上:msdn.microsoft.com/en-us/library/… Section:"Guidelines for FlagsAttribute and Enum" 提供了额外的最佳实践。
  • 为什么使用 0 作为值是个坏主意?
【解决方案2】:

你应该给你的枚举赋值。 flags 属性所做的只是改变 ToString 方法的工作方式。我会使用按位运算符来减少出错的可能性:

[Flags]
public enum ItemType
{
    Shop = 1 << 0, // == 1
    Farm = 1 << 1, // == 2
    Weapon = 1 << 2, // == 4
    Process = 1 << 3, // == 8
    Sale = 1 << 4 // == 16
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-07
    相关资源
    最近更新 更多