如何编写谓词函数



我有一个这样的类:

public class A
{
public string Username { get; set; }
public bool IsOK { get; set}
}
public class B:A
{
public string test { get; set; }
}
public class C:B
{
public string test2 { get; set; }
}

在我的主要班级:

static void main()
{
var a = new B() { Username = "User1", IsOK = false };
var b = new B() { Username = "user2", IsOK = false };
var c = new C() { Username = "admin", IsOK = true };
List<B> bclasses = new List<B>() { a, b, c };
// I want to filter out username is user2 or IsOK is true
var username = "user2";
var select = bclasses.Where(b => b.IsOK || b.Username == username).ToList();
}

但我不想每次都写代码"b=>b.IsOk||b.UserName==UserName"。我怎样才能在Where里面写一个谓词,使它简洁?谢谢

您可以将谓词声明为Func<A, bool>:

Func<A, bool> predicate = x => x.IsOK || x.Username == username;

或者您可以将其声明为本地函数:

bool predicate(A x) => x.IsOK || x.Username == username;

(不幸的是,您不能使用Predicate<A>,因为它不是IEnumerable.Where()所接受的类型。(

在任何一种情况下,如果它是在方法内部定义的,它可以捕获本地username,因此不需要为此设置参数。

以下是一个经过更正且可编译的示例:

using System.Collections.Generic;
using System.Linq;
namespace Demo
{
public class A
{
public string Username { get; set; }
public bool   IsOK     { get; set; }
}
public class B: A
{
public string test { get; set; }
}
public class C: B
{
public string test2 { get; set; }
}
static class Program
{
public static void Main()
{
var     a        = new B() { Username = "User1", IsOK = false };
var     b        = new B() { Username = "user2", IsOK = false };
var     c        = new C() { Username = "admin", IsOK = true };
List<B> bclasses = new List<B>() { a, b, c };
// I want to filter out username is user2 or IsOK is true
var username = "user2";
bool predicate(A x) => x.IsOK || x.Username == username; // <=== Here is the predicate.
var select = bclasses.Where(predicate).ToList();
}
}
}

现在,假设您实际上想将username参数传递给谓词,而不是捕获它,那么您只需向谓词添加一个参数,如下所示:

bool predicate(A x, string name) => x.IsOK || x.Username == name;

然后将username传递给Where()中的谓词,如下所示:

var select = bclasses.Where(item => predicate(item, username)).ToList();

您需要一个接受B或C的函数,并返回一个指示是否将其包含在列表中的布尔值。换句话说,一个Func<B,bool>。你可以这样定义它:

Func<B,bool> predicate = x => x.IsOK || x.Username == username;

要使用它,只需将它传递给Where即可。

var selection = bclasses.Where( predicate ).ToList();

在这种情况下,我认为您可能需要实现Function(Func(,而不是Predicate。

感谢@Fildor为我指出未使用的委托,以便我将其封装为以下内容:

Func<List<A>, string, List<A>> selectValidUser = (users, filterName) =>
{
return users.Where(u => u.IsOK || u.Username == filterName).ToList();
};
var selectedUsers = selectValidUser(bclasses, username);

最新更新