C#将单值枚举与标志枚举结合起来

时间:2015-11-30 13:34:08

标签: c# enums

我想使用标志枚举作为过滤器来过滤单个值枚举。

当我使用一个标志枚举来提供两者时,我有两个异议:

  • 命名约定状态比标志枚举是复数,而单个项目枚举不是;

  • 我希望filter / flags枚举的值为" none"和"所有",但在不用作过滤器时这些值不是有效值;

说明我的意图的一个例子(但是由于两个枚举之间的类型不兼容而无法正常运行)

    enum Material
    {
        wood,
        metal,
        plastic
    }

    [Flags]
    enum Materials
    {
        none = 0,
        wood = 1,
        metal = 2,
        plastic = 4,
        all = 7
    }

    var filter = Materials.all;

    foreach (article in articles.Where(a => Filter.HasFlag(a.FinishMaterial))
        ...

如上所述,这个例子没有做我想要的。 仅使用Materials枚举感觉不太好,因为没有和所有都不是文章完成的有效值。

我可以使用一些转换为int来在两个枚举之间进行转换。但是应该有更优雅,更杂乱的方式来做到这一点,对吗?

[丹尼斯回答后编辑] 我确实考虑过使用集合作为过滤器。此外,它感觉重量大,需要更多的代码,而使用枚举是轻量级的。然而,当我没有完成这项工作时,我没有任何用户,轻盈/优雅与否......

[标记为ansered后编辑] 谢谢大家的投入!

3 个答案:

答案 0 :(得分:0)

IMO,使用集合来保存过滤器比操作标志更容易和可读:

// This is equivalent of "var filter = Materials.all";
// an empty collection is equivalent of "Materials.None"
var filter = (Material[])Enum.GetValues(typeof(Material));
// use next line, if you need to modify the filter:
// var filter = ((Material[])Enum.GetValues(typeof(Material))).ToList();

foreach (article in articles.Where(a => filter.Contains(a.FinishMaterial)))
{
    // ...
}

答案 1 :(得分:0)

你有2个解决方案:

首先:

Material value = (Material)Enum.Parse(typeof (Material), Materials.wood.ToString());

即。转换枚举

第二:仅使用Materials枚举。不清楚但很简单。

答案 2 :(得分:0)

最佳方式是使用int转化而不是Enum.Parse。要使用HasFlag解决问题,您可以创建扩展方法。以下是带测试的代码

[TestClass]
public class MaterialsTests
{
    [TestMethod]
    public void Contains_wroks_as_expected()
    {
        var filter = Materials.all;
        Assert.IsTrue(filter.Contains(Material.metal));
    }
}

public static class Extensions
{
    public static bool Contains(this Materials filter, Material material)
    {
        var valueToFilter = (Materials)(int)(material);
        return filter.HasFlag(valueToFilter);
    }
}

public enum Material
{
    wood = 1,
    metal = 2,
    plastic = 4
}

[Flags]
public enum Materials
{
    none = 0,
    wood = 1,
    metal = 2,
    plastic = 4,
    all = 7
}