c# - 如何将通用选择器 Func<T, U> 传递给某些方法以执行搜索?

标签 c# linq search lambda

我有一个包含一些字段的类。

public abstract class RegisteredUser : Transformable //implements interface
{
    protected int id;
    protected bool active;
    protected string name;
    protected string lastName;
    protected string email;
    protected string username;
    protected string password;
    protected int institution;

//OTHER  STUFF FROM  THIS CLASS GO HERE..`
} 
Assistant : RegisteredUser
{
}

一旦我从 .txt 文件加载所有数据,我将拥有一个如下所示的静态字典:

public static Dictionary<int, Transformable> assistants = null; //this will be filed with objects and their id's

现在,我的任务是实现此控制台应用程序的搜索功能。由于所有子类都将具有来自抽象类的字段,因此该应用程序的用户应该可以选择搜索任何对象AssistantProfessorAdministrator 通过其任何字段。

我想通过使用LINQ/lambdas来实现这一点。我的想法是创建一些通用方法,该方法将根据正在搜索的任何字段接受选择器(或某些 lambda 表达式)。

我对 LINQ 和 C# 以及编程来说都是全新的,所以我希望我没有在这里胡说八道。

public static List<RegisteredUser> search(Dictionary<int, Transformable> map, 
                                          Func<bool,RegisteredUser> selector, 
                                          Transformable userType)
{
    if (userType is Assistant)
    {
        List<RegisteredUser> list = map.Select(item => (Assistant) item.Value)
                                       .ToList()
                                       .Select(selector)
                                       .ToList();
    }
    //other if/else statements  

    return list;
}

当然,Visual Studio 中的线条是红色的:) 基本上,我希望能够发送类似的内容 user => user.Name.Contains("最终用户将输入的某个字符串") 到通用函数。

最佳答案

你并不需要编写一个单独的函数来完成你想要实现的目标,这一切都可以通过Linq来完成。直接:

var users = new Dictionary<int, Transformable>
{
     {0, new Assistant { Name = "Joe" }},
     {1, new Professor { Name = "John" }},
     {2, new Assistant { Name = "Jane" }}
};

var assistants = users.Values.OfType<Assistant>().Where(a => a.Name == "Jane");

assistantsIEnumerable<Assistant>名称等于“Jane”,并且仅包含上述字典中的 1 个条目。您可以将 ToList() 添加到其末尾来创建列表

然后您可以添加所需的任何谓词:

var assistants = users.Values.OfType<Assistant>().Where(a => a.Name == "Jane" && a.LastName == "Smith" && a.Active);

您可以将上面的内容包装在一个函数中,但最终得到的内容不会比上面的短很多。

作为扩展方法,它会是这样的:

public static class Extensions
{
    public static IEnumerable<T> Find<T>(this IEnumerable<Transformable> list, Func<T,bool> predicate) where T :Transformable
    {
        return list.OfType<T>().Where(predicate.Invoke);
    }
}

使通话时间稍微短一些:

var assistants = users.Values.Find<Assistant>(a => a.Name == "Jane");

这是流畅 API 模式的示例,因此您可以像任何其他 Linq 函数一样在 Linq 链中使用它。

关于c# - 如何将通用选择器 Func<T, U> 传递给某些方法以执行搜索?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58572640/

相关文章:

linq - 如何将此 SQL 查询转换为 LINQ to SQL

c# - 具有父子关系的 Linq to sql 查询

java - 使用自己的类在 ArrayList 中查找字符串值

使用 EdgeNGramFilterFactory 和搜索查询的最小长度在 Solr 中搜索

php - 按首字母排序sql查询

c# - 如何将变量传递给任务工厂操作?

c# - 在 LINQ 中对多个表进行分组

c# - 在多个线程之间共享一个 List<T>

c# - 在 BrowserBack 上调用的已注册警报脚本

c# - 删除图片的url但图片不删除