具有两个参数的 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; }
}
我有一个传递给 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; }
}