其他方法用于遍历枚举 [英] Other method for iterating an enum

查看:150
本文介绍了其他方法用于遍历枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

起初,我有以下几点:

[Flags]
public enum QueryFlag
{
    None = 0x00,
    CustomerID = 0x01,
    SalesPerson = 0x02,
    OrderDate = 0x04
}

由于复选框被选中/取消选中,我想添加/删除标志:

As check boxes are checked/unchecked, I would add/remove flags from:

QueryFlag qflag;

我的想法 - 当用户点击搜索按钮,我会遍历在 qflag 设置实际的标志修改。凡在我的LINQ to SQL子句。然而, Enum.GetValues​​(qflag.GetType())返回QueryFlag本身的所有值。没有帮助的。

My idea - when the user clicks the Search button, I would iterate the actual flags set in qflag to modify a .Where clause in my LINQ to Sql. However, Enum.GetValues(qflag.GetType()) returns all the values of the QueryFlag itself. Not helpful.

我的解决办法:

class myForm : Form
{
    List<QueryFlag> qflag = new List<QueryFlag>();

    private void chkOrderDate_CheckedChanged(object sender, EventArgs e)
    {
        if (chkOrderDate.Checked && !qflags.Contains(QueryFlag.OrderDate))
            qflags.Add(QueryFlag.OrderDate);
        else
            qflags.Remove(QueryFlag.OrderDate);
    }

    private void cmdSearch_Click(object sender, EventArgs e)
    {
        if (qflags.Count == 0)
        {
            rtfLog.AppendText("\nNo search criteria selected.");
            return;
        }

        foreach (QueryFlag flag in qflag)
        {
            rtfLog.AppendText(string.Format("\nSearching {0}", flag.ToString()));

            // add switch for flag value
        }
    }
}

public enum QueryFlag
{
    CustomerID,
    SalesPerson,
    OrderDate
}

我有3个复选框,这工作没​​有任何问题,这点。但我想知道是否有更好的方法来执行本次迭代。

I have 3 check boxes and this works without any issues to this point. But I am wondering if there is a better way to perform this iteration.

推荐答案

你有它原来是正确的方式;你刚刚搞砸了 Enum.GetValues​​ 方法。这个方法返回一个特定的每一个定义的值枚举键入,是的。所以,你的执行的使用,这是检查每一个的定义的值对你的尤其枚举价值看到所定义的值是否设置你的价值之内。

The way you had it originally was correct; you just got messed up by the Enum.GetValues method. This method returns every defined value for a particular enum type, yes. So what you do with this is check each defined value against your particular enum value to see whether the defined value is set within your value.

也就是说,你的应该的做到这一点:

That is, you should do this:

private void chkOrderDate_CheckedChanged(object sender, EventArgs e)
{
    if (chkOrderDate.Checked)
    {
        qFlag |= QueryFlag.OrderDate;
    }
    else
    {
        qFlag &= (~QueryFlag.OrderDate);
    }
}

......,同样为您的其他复选框。然后,当你想列举什么标志已设置:

...and likewise for your other CheckBoxes. Then when you want to enumerate what flags you have set:

static IEnumerable<QueryFlag> GetFlags(QueryFlag flags)
{
    foreach (QueryFlag flag in Enum.GetValues(typeof(QueryFlag)))
    {
        // Presumably you don't want to include None.
        if (flag == QueryFlag.None)
        {
            continue;
        }

        if ((flags & flag) == flag)
        {
            yield return flag;
        }
    }
}

事实上,你甚至可以抽象到上述所有枚举类型的一个方便的扩展方法:

In fact, you could even abstract the above into a handy extension method for all enum types:

public static class FlagsHelper
{
    // This is not exactly perfect, as it allows you to call GetFlags on any
    // struct type, which will throw an exception at runtime if the type isn't
    // an enum.
    public static IEnumerable<TEnum> GetFlags<TEnum>(this TEnum flags)
        where TEnum : struct
    {
        // Unfortunately this boxing/unboxing is the easiest way
        // to do this due to C#'s lack of a where T : enum constraint
        // (there are ways around this, but they involve some
        // frustrating code).
        int flagsValue = (int)(object)flags;

        foreach (int flag in Enum.GetValues(typeof(TEnum)))
        {
            if ((flagsValue & flag) == flag)
            {
                // Once again: an unfortunate boxing/unboxing
                // due to the lack of a where T : enum constraint.
                yield return (TEnum)(object)flag;
            }
        }
    }
}

所以,你的 cmdSearch_Click 的处理器也可以是这样的:

So your cmdSearch_Click handler could look like this:

private void cmdSearch_Click(object sender, EventArgs e)
{
    if (qFlag == QueryFlags.None)
    {
        rtfLog.AppendText("\nNo search criteria selected.");
        return;
    }

    foreach (QueryFlag flag in qFlag.GetFlags())
    {
        rtfLog.AppendText(string.Format("\nSearching {0}", flag.ToString()));

        // add switch for flag value
    }
}

这篇关于其他方法用于遍历枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆