4

位标志有点难以理解:)

我知道这个这个问题,我确实理解答案,我什至从我的一个好朋友那里关注了这篇文章。

但是当我需要“进化”超过标准时,我仍然无法弄清楚......

我想要做的是:

    if (HttpContext.Current.Session["DebugSessionText"] != null)
    {
        showType = parDebug.Write2LogType.WARN | 
                   parDebug.Write2LogType.ERROR | 
                   parDebug.Write2LogType.INFO;

        if (!chkInfo.Checked)
            showType &= ~parDebug.Write2LogType.INFO;  // remove INFOs        
        if (!chkError.Checked)
            showType &= ~parDebug.Write2LogType.ERROR; // remove ERRORs

        List<myDebugRow> list =
            (List<myDebugRow>)HttpContext.Current.Session["DebugSessionText"];

        gv.DataSource = list.FindAll(x => x.Type == showType));
    }
    gv.DataBind();

我确实需要过滤一个 List 对象,这样我才能得到用户想要的东西(只显示 INFO 错误、异常错误,但总是会显示 WARNing 错误)......

有没有直接的方法可以做到这一点,或者我需要在不使用 LAMBDA 表达式的情况下手动过滤它?

谢谢大家的帮助。

4

3 回答 3

10

x.Type == showType

您只会得到与所有条件(位标志)完全匹配的项目。和

(x.Type & showType) != 0

您会发现所有与 showType 至少有 1 位匹配的项目,这可能是您想要的。

于 2009-10-15T17:31:26.550 回答
9

如果您发现这些操作令人困惑——坦率地说,我确实如此——然后考虑提高抽象级别。给自己写一些辅助扩展方法。

static WriteToLogType AddWarn(this WriteToLogType x) { return x | WriteToLogType.WARN; }
static WriteToLogType ClearWarn(this WriteToLogType x) { return x & ~WriteToLogType.WARN; }
static bool HasWarn(this WriteToLogType x) { return 0 != (x & WriteToLogType.WARN); }
// same for Error, Info
static bool HasExactly(this WriteToLogType x, WriteToLogType y) { return x == y; }
static bool HasAny(this WriteToLogType x, WriteToLogType y) { return 0 != (x & y); }
static bool HasAll(this WriteToLogType x, WriteToLogType y) { return y == (x & y); }

现在你的程序变成了

    showType = WriteToLogType.None.AddWarn().AddInfo().AddError();
    if (!chkInfo.Checked) showType = showType.ClearInfo();
    if (!chkError.Checked) showType = showType.ClearError();
    List<myDebugRow> list = whatever;
    gv.DataSource = list.FindAll(x => x.Type.HasAny(showType)));

我希望你同意这一点比所有那些琐碎的事情要清楚得多。但我们仍然可以更清楚地说明这一点。

    showType = WriteToLogType.None.AddWarn();
    if (chkInfo.Checked) showType = showType.AddInfo();
    if (chkError.Checked) showType = showType.AddError();
    List<myDebugRow> list = whatever;
    gv.DataSource = list.FindAll(x => x.Type.HasAny(showType)));

与其添加一堆标志然后将它们拿走,不如一开始就不要添加它们。

于 2009-10-15T18:04:29.427 回答
2
gv.DataSource = list.FindAll(x => x.Type == showType));

应该

gv.DataSource = list.FindAll(x => 0 != (x.Type & showType)));

因为您不希望 Type 与 showType 完全相同,对吧?您可以手动迭代列表并进行比较并删除您不需要的内容,尽管我不确定这是一个优雅的解决方案。

于 2009-10-15T17:29:29.750 回答