我有一个这样的班级:
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 ==用户名”。 我如何在Where中写一个谓词,以便简洁? 谢谢。
答案 0 :(得分:1)
在这种情况下,我认为您可能需要实现功能(Func),而不是谓词。
感谢@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);
答案 1 :(得分:1)
您需要一个接受B或C并返回布尔值的函数,该布尔值指示是否将其包括在列表中。换句话说,是Func<B,bool>
。您可以这样定义它:
Func<B,bool> predicate = x => x.IsOK || x.Username == username;
要使用它,只需将其传递给Where
。
var selection = bclasses.Where( predicate ).ToList();
答案 2 :(得分:1)
您可以将谓词声明为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();