具有两个参数的 FirstOrDefault 的 Lambda 表达式

Lambda Expression for FirstOrDefault with two parameters

我有一个传递给 First()FirstOrDefault() 调用的 lambda 表达式。

我想在 lambda 执行时动态注入一个参数值。

这是我现在的破解代码;它在运行的意义上“有效”。

ObservableCollection<T> Rows { get; set; }

T currentRow = Rows[0];
Template r = (Template)(object)currentRow;

Func<T, bool> p = e => ((Template)(object)e).TemplateId.Equals(r.TemplateId);

var firstRow = Rows.First(p);

我想要能够正确处理通用 T 的东西

public class Model<T>
{
    public ObservableCollection<T> Rows { get; set; } = {add rows here}
    
    public Func<T, T, bool> Lambda { get; set; }
    
    public T CompareRow {get; set;} // assume not null
    public T SelectedRow { get; set; }

    public GetRow()
    {
       T currentRow = CompareRow; 

       // First extension takes a lambda expression of Func<T,bool>
       // SOMEHOW inject the runtime value of currentRow into lambda
       // to convert Func<T, T, bool> to Func<T, bool>

       var firstRow = Rows.First(Lambda);  // get first row that matches Lamda

       SelectedRow = firstRow;
    }
} 

public class MyModel: Model<Entity>
{
    public void MyModel()  : base()
    {
       // define the lambda expression with the concrete type of <Entity>
       // each <Entity> type has different fields;
       // so want to define a Lambda in the concrete class to validate the fields,
       // but one that can be used in the generic base class.

       Func<Entity, Entity, bool> p = (e,r) => e.TemplateId.Equals(r.TemplateId);
       Lambda = p;
    }

    public SetRow()  // called from somewhere
    {
       CompareRow = Rows.Last();  // assume Rows is not empty
    }

    public GetRow()
    {
        base.GetRow();
    }
}

我找到了这些...

[ (这里面有额外的代码...所以可以改进吗?)

[ (这特定于创建“select”lambda)。

[https://www.codementor.io/@juliandambrosio/how-to-use-expression-trees-to-build-dynamic-queries-c-xyk1l2l82]

[

另外:如果有不同的调用方式

var firstRow = Rows.First(Lambda);

直截了当,欢迎提出建议。

您可以通过这种方式调用您的 Lambda 函数。

public GetRow()
{
   T currentRow = CompareRow; 
   var firstRow = Rows.First(row => Lambda(row, CompareRow));  // get first row that matches Lambda

   SelectedRow = firstRow;
}

这是另一个使用 string 参数的例子:

List<string> names = new() { "Alice", "Bob", "Charlie" };
string nameToMatch = "Alice";
Func<string, string, bool> Lambda = (left, right) => left.GetHashCode() == right.GetHashCode();
var alice = names.First(name => Lambda(name, nameToMatch));
Console.WriteLine($"Hi {alice}");

您在设置 Lambda 时可能遇到了一些问题。类型看起来不对 Func<Entity, Entity, bool> 不是 Func<T, T, bool> 因为对 T 是什么类型没有限制。

您可能需要考虑在 T 上添加约束,可能是这样的:

public class Model<T>
   where T : Entity
{
    public Func<Entity, Entity, bool> Lambda { get; set; }
}