是否可以在 C# 中使用自定义值或模板化值创建谓词

unk*_*SPY 2 c# predicate list

我对 C# 比较陌生,并且来自 C++ 背景。我一直在寻找列表搜索和Find.

我试图定义一个函数,它接受一个参数,并从列表中返回一个条目。例如

class Product
{
    public string id;
    public string description;
}

public List<Product> products = new List<Product>();
// Add some items to the list
Run Code Online (Sandbox Code Playgroud)

我的问题是,我可以使用 Predicates/Funcs 等 C# 功能打开以下自定义“查找”函数吗?

Product GetProductByID(string id)
{
    foreach (Product p in products)
    {
        if (p.id == id)
        {
            return p;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我曾尝试使用谓词,但我似乎无法找到无论如何将值提供给函数来执行布尔表达式检查。我了解如何编写 Predicate 来查找列表中的特定项,而不是可以传入的动态项。

理想情况下,我想更进一步并为其模板化,以便 Predicate 可用于具有类似结构的任何项目列表。

即如果我们也有

class Employee
{
    public string id;
    public int age;
}

public List<Employee> employees = new List<Employee>();
// Add some items to the list
Run Code Online (Sandbox Code Playgroud)

使用相同定义的 Predicate 真的很酷,但是在这个完全不同类型的列表上。即像

// psudo
Predicate<T, string> predicate = return <T>.id == id;
Run Code Online (Sandbox Code Playgroud)

并且它起作用是因为 T 总是具有一个名为的字符串成员的类型 id

我希望这一切都有意义。

Jon*_*eet 5

我了解如何编写 Predicate 来查找列表中的特定项,而不是可以传入的动态项。

这就是 lambda 表达式的用武之地,它允许您创建一个委托类型的实例来捕获范围内的变量。例如:

public Predicate<Product> CreateProductPredicateForId(string id)
{
    return product => product.id == id;
}
Run Code Online (Sandbox Code Playgroud)

现在就制作泛型而言,您需要有一个指定Id属性的接口。然后您可以编写一个泛型方法。例如:

public interface IEntity
{
    string Id { get; }
}
...

public Predicate<T> CreatePredicateForId<T>(string id) where T : IEntity
{
    return entity => entity.Id == id;
}
Run Code Online (Sandbox Code Playgroud)