繁体   English   中英

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

[英]Lamda Expression for FirstOrDefault with two parameters

我有一个传递给 First() 或 FirstOrDefault() 调用的 lamda 表达式。 我想在执行时将参数值动态注入lamda。

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

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> Lamda { get; set; }
    
    public T CompareRow {get; set;} // assume not null
    public T SelectedRow { get; set; }

    public GetRow()
    {
       T currentRow = CompareRow; 

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

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

       SelectedRow = firstRow;
    }
} 

public class MyModel: Model<Entity>
{
    public void MyModel()  : base()
    {
       // define the lamda expression with the concrete type of <Entity>
       // each <Entity> type has different fields;
       // so want to define a Lamda 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);
       Lamda = p;
    }

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

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

我找到了这些...

[https://stackoverflow.com/questions/16985310/convert-expressionfunct-t-bool-to-expressionfunct-bool](这里面有额外的代码......所以可以改进吗?)

[https://stackoverflow.com/questions/21922214/create-dynamic-linq-expression-for-select-with-firstordefault-inside](这是特定于创建“选择”lamda)。

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

[https://stackoverflow.com/questions/63172233/dynamic-firstordefault-predicate-expression]

另外:如果有不同的方法来调用var firstRow = Rows.First(Lamda); 这是直截了当的,欢迎提出建议。

您可以通过这种方式调用您的 Lamda function。

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

   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> Lamda { get; set; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM