簡體   English   中英

C#將單值枚舉與標志枚舉組合

[英]C# combining single value enum with flags enum

我想將標志枚舉用作過濾器集,以對單個值枚舉進行過濾。

當我使用一個標志枚舉來同時提供兩者時,我有兩個反對意見:

  • 命名約定規定,標志枚舉數是復數,而單個項枚舉不是。

  • 我希望過濾器/標志枚舉具有“無”和“全部”的值,但是當不用作過濾器時這些值不是有效值;

說明我的意圖的示例(但由於兩個枚舉之間的類型不兼容而無法正常運行)

    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在兩個枚舉之間進行轉換。 但是應該有一種更優雅,更整潔的方式來做到這一點,對嗎?

[丹尼斯回答后編輯]實際上,我確實考慮過使用集合作為過濾器。 同時感覺很重,需要更多代碼,而使用枚舉則是輕量級的。 但是,當is不能完成任務時,我沒有用戶使用它,無論lightweigt / elegant ...

[標記為回復后的編輯]謝謝大家的投入!

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)))
{
    // ...
}

最佳方法是使用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
}

您有2個解決方案:

第一:

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

即轉換枚舉

第二:僅使用材料枚舉。 不清楚但很簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM