【问题标题】:How to combine c# predicates如何组合c#谓词
【发布时间】:2016-09-28 10:18:32
【问题描述】:

嗨,我有两个谓词。我想知道是否有可能以某种方式将它们结合在一起? 第一:

Predicate<object> viewFilter = f =>
{
    ExternalUser u = f as ExternalUser;
    return u.AgentName.ToLower().StartsWith(agentName.ToLower());
};

第二:

Predicate<object> viewFilter = f =>
{
    ExternalUser u = f as ExternalUser;
    return u.ExternalLogin.ToLower().StartsWith(login.ToLower());
};

这就是连接谓词的样子。

Predicate<object> viewFilter = f =>
{
    ExternalUser u = f as ExternalUser;
    return u.ExternalLogin.ToLower().StartsWith(login.ToLower()) && u.AgentName.ToLower().StartsWith(agentName.ToLower());
};

我需要这个用于 WPF 数据网格过滤器,其中网格源是 ICollectionView。 所以在我创建了我的谓词之后,我将它设置为这样的过滤器:

private void FilterByLogin(ICollectionView view, string login)
{
    Predicate<object> viewFilter = f =>
    {
        ExternalUser u = f as ExternalUser;
        return u.ExternalLogin.ToLower().StartsWith(login.ToLower());
    };
    view.Filter = viewFilter;
}

【问题讨论】:

  • 除了问题;为什么你使用 as 而不检查 null ?这意味着您现在可以确定类型只需使用简单的转换(ExternalUser) f。这样,当由于某种晦涩的原因失败时,你会得到一个 InvalidCastException 而不是 NullReferenceException,这更清楚问题是什么
  • 附注:如果您不检查 null,请不要使用 as。而是直接施法。 ExternalUser u =(ExternalUser) f;

标签: c# wpf


【解决方案1】:

我会创建两个新方法:

public static Prediate<object> Cast<T>(Predicate<T> inner)
{
    return new Predicate<object>(o => inner((T)o));
}

public static Predicate<T> And<T>(Predicate<T> p1, Predicate<T> p2)
{
    return x => p1(x) && p2(x);
}

然后您可以从谓词中删除强制转换并将其移至顶层:

Predicate<ExternalUser> first = u => u.AgentName.ToLower().StartsWith(agentName.ToLower());
Predicate<ExternalUser> second = u => u.ExternalLogin.ToLower().StartsWith(login.ToLower());

view.Filter = Cast(And(first, second));

【讨论】:

    【解决方案2】:

    真的应该这么简单:

    Predicate<object> viewFilter1 = f =>
    {
        ExternalUser u = f as ExternalUser;
        return u.AgentName.ToLower().StartsWith(agentName.ToLower());
    };
    
    Predicate<object> viewFilter2 = f =>
    {
        ExternalUser u = f as ExternalUser;
        return u.ExternalLogin.ToLower().StartsWith(login.ToLower());
    };
    
    Predicate<object> viewFilter = f => viewFilter1(f) && viewFilter2(f);
    

    【讨论】:

      猜你喜欢
      • 2010-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多