混淆使用c#Predicate

时间:2018-05-31 07:39:25

标签: c#

我有以下IEnumerable<>列表,我正在寻找一个值。如果它在那里它会返回true:

  RepositoryForDashboard rp = new RepositoryForDashboard();
  IEnumerable<ListOfAuthorizedUserForTestDashBoard> usersForT = rp.listOfusersForT();

值为“username”,我看起来像这样:

 if(usersForT.Any(e=>e.userID==username))

它工作正常,但由于我是c#的新手,我想学习如何使用Predicate委托编写它,这给了我错误:

   Predicate<string> isInList=delegate(username){usersForT.Any(e=>e.userID==username)};

2 个答案:

答案 0 :(得分:2)

根据评论中的要求,这里是使用代码作为变量的示例。在这种情况下,用户管理器上的函数UserMatchingCriteriaExists接受用于测试是否存在与给定条件匹配的任何用户的单个谓词。通过让这个函数接受一个谓词而不仅仅是用户名,给定的名字和姓氏,我们允许该方法比该类可能想象的编码器更有用。例如。当前逻辑仅根据提供的标准的AND过滤匹配字符串;这很简单。但是,如果使用我们的UserManager的用户有一个用例,他们想要查找大写的所有用户名,或者名字与姓氏匹配的用户名等,我们的UserMatchingCriteriaExists方法可以处理;客户端只需要创建所需的谓词。

Dot Net Fiddle Example(从下面略微调整以适应旧版本的C#)。

void Main()
{
    //create a reference to our user manager
    var userManager = new UserManager();

    //run some demos with different search criteria
    SearchAndDisplay(userManager, null, "Anne", "Droid"); //should return true
    SearchAndDisplay(userManager, null, "Anne", "Borgue"); //should return false
    SearchAndDisplay(userManager, null, "Simon", "Borgue"); //should return true
    SearchAndDisplay(userManager, "Two", null, null); //sshould return true
    SearchAndDisplay(userManager, "Four", null, null); //should return false
    SearchAndDisplay(userManager, null, null, null); //should return true (as we've not given any filter criteria, and users do exist)
    SearchAndDisplay(new UserManager(true), null, null, null); //should return true (as we've not given any criteria, but no users exist so there is no match)
}
void SearchAndDisplay(UserManager userManager, string searchByUsername, string searchByGivenName, string searchBySurname)
{
    //build up our query
    Predicate<User> searchCriteria = And<User>(); //`And` with no arguments is simply `true`
    if (!string.IsNullOrEmpty(searchByUsername)) searchCriteria = And<User>(searchCriteria, user => searchByUsername.Equals(user?.Username, StringComparison.InvariantCultureIgnoreCase));
    if (!string.IsNullOrEmpty(searchByGivenName)) searchCriteria = And<User>(searchCriteria, user => searchByGivenName.Equals(user?.GivenName, StringComparison.InvariantCultureIgnoreCase));
    if (!string.IsNullOrEmpty(searchBySurname)) searchCriteria = And<User>(searchCriteria, user => searchBySurname.Equals(user?.Surname, StringComparison.InvariantCultureIgnoreCase));

    //search the users using the criteria defined above; NB: The user manager does not need to know anything about our query logic, so our client has lots of flexibility in what queries it can use / is not restricted by the UserManager's implementation
    var result = userManager.UserMatchingCriteriaExists(searchCriteria);

    //display some output to show the user what we've done
    Console.WriteLine($"Search Criteria:\n\tUsername: {searchByUsername ?? "not searched"}\n\tGivenName: {searchByGivenName ?? "not searched"}\n\tSurname: {searchBySurname ?? "not searched"}\nFound: {result}");
}
///Holds basic user information
class User 
{
    public User(){}
    public string Username{get; set;}
    public string GivenName{get; set;}
    public string Surname{get; set;}
}
///Holds the collection of users & allows operations against them
class UserManager 
{
    readonly IEnumerable<User> users;
    public UserManager(): this(false) {}
    public UserManager(bool noUsers)
    {
        if (noUsers) 
        {
            users = new User[]{};
        }
        else
        {
            users = new User[]
            {
                new User(){Username = "one", GivenName = "Anne", Surname = "Droid"}
                ,new User(){Username = "two", GivenName = "Simon", Surname = "Borgue"}
                ,new User(){Username = "three", GivenName = "Alex", Surname = "Arnold"}
            };
        }
    }
    public bool UserMatchingCriteriaExists(Predicate<User> criteria)
    {
        return users.Any(user => criteria(user));
    }
}
///Allows us to combine predicates
Predicate<T> And<T>(params Predicate<T>[] predicates)
{
    return delegate (T item)
    {
        foreach (var predicate in predicates)
        {
            if (!predicate(item))
            {
                return false;
            }
        }
        return true;
    };
}

答案 1 :(得分:1)

您的代码中存在语法错误,您也可以使用lambda,这将使您更容易ex:

True

或者如果使用委托,请包含类型和MyObjectList:=Nil; // This will actually free the whole list and Nil it; MyObjectList.Free; // This will actually free the whole list but not Nil it; 声明:

Predicate<string> isInList = item => usersForT.Any(e=>e.userID==item);