C# Lambda表达式与搜索
假设我有一个表单,它包含以下内容: 名称:文本框C# Lambda表达式与搜索,c#,linq,search,lambda,C#,Linq,Search,Lambda,假设我有一个表单,它包含以下内容: 名称:文本框 电子邮件:文本框 年龄:文本框 现在,我想基于此过滤器文本框获取客户集合 因此,我想使用如下内容: List<customer> customers = getCustomerswhere(c=>c.name == txtName.Text && Email == txtEmail.Text); 我该怎么做!我不能连接lambda表达式,我知道我可以使用动态表达式,但我认为有更简单的方法吗?你知道如何实现这一点
电子邮件:文本框
年龄:文本框 现在,我想基于此过滤器文本框获取客户集合 因此,我想使用如下内容:
List<customer> customers = getCustomerswhere(c=>c.name == txtName.Text && Email == txtEmail.Text);
我该怎么做!我不能连接lambda表达式,我知道我可以使用动态表达式,但我认为有更简单的方法吗?你知道如何实现这一点吗
好的,我试过这个:
Func<Customer,bool > a = (bb) => bb.fullName == "asdfsd";
Func<Customer, bool> b = c => c.lastName == "sdas";
Func<Customer, bool> cc = c => a(c) && b(c);
Func a=(bb)=>bb.fullName==“asdfsd”;
Func b=c=>c.lastName==“sdas”;
Func cc=c=>a(c)和b(c);
现在又来了一个问题
我传递CC给的方法需要Expression
所以它不工作给我编译时错误不能在类型之间转换 您可以创建一些表达式,如:
var a = c => c.name == txtName.Text;
var b = c => c.name == txtName.Text;
然后像这样连接它们:
var result = c => a(c) && b(c);
像这样:
Func<Customer, bool> predicate = c => true;
if (txtName.Text.Trim() != "")
predicate = Concatenate(predicate, c => c.Name == txtName.text);
if (txtEmail.Text.Trim() != "")
predicate = Concatenate(predicate, c => c.Email == txtEmail.text);
static Func<T, bool> Concatenate(Func<T, bool> a, Func<T, bool> b) {
return t => a(t) && b(t);
}
将导致堆栈溢出,因为谓词
变量将始终引用您分配给它的最新不可变委托实例
return Customers.Where(c => (txtName.Text.Trim() == "" || c.Name == txtName.Text)
&& (txtEmail.Text.Trim() == "" || c.Email == txtEmail.Text));
换句话说,如果填写了“姓名”框,则仅施加“姓名”条件;如果填写了“电子邮件”框,则仅施加“电子邮件”条件
请注意,您可以在.NET 4.0中使用
String.IsNullOrWhiteSpace
方法,而不是使用修剪技术。以下是我如何实现它的:
public class LambdaCriteries<T> : List<Expression<Func<T, bool>>>
{
public Expression<Func<T, bool>> GetFinalLambdaExpression()
{
var par = Expression.Parameter(typeof(T));
var intial = Expression.Invoke(this.First(),par);
var sec = Expression.Invoke(this.Skip(1).First(),par);
BinaryExpression binaryExpression = Expression.And(intial, sec);
if (this.Count> 2)
{
foreach (var ex in this.ToList().Skip(2))
{
binaryExpression = Expression.And(binaryExpression, Expression.Invoke(ex, par));
}
return Expression.Lambda<Func<T, bool>>(binaryExpression,par);
}
else
{
return Expression.Lambda<Func<T, bool>>(binaryExpression,par);
}
}
}
最后一句话:
var finalexp = criteries.GetFinalLambdaExpression();
是的,但问题是我将失去IntelisSense,我尝试了var a=(客户C)=>C.name==txtName.Text;但它给了我编译时错误:无法将lambda表达式指定给隐式类型的本地variable@Zeus这不是lambda表达式的错误,只是一个要求,即指定您希望创建的委托的类型,在您的情况下,您可以编写谓词或Func。不,不要松开安全带。唯一的松散对象是动态的。为什么会导致堆栈溢出?委托是不可变的,所以我希望RHS上的谓词引用的对象与分配给LHS@Rune:lambda将通过引用来绘制变量。调用
谓词(c)
时,谓词
变量将引用变量中的当前不可变委托实例,即调用lambda表达式。请取消你的否决票。
public class LambdaCriteries<T> : List<Expression<Func<T, bool>>>
{
public Expression<Func<T, bool>> GetFinalLambdaExpression()
{
var par = Expression.Parameter(typeof(T));
var intial = Expression.Invoke(this.First(),par);
var sec = Expression.Invoke(this.Skip(1).First(),par);
BinaryExpression binaryExpression = Expression.And(intial, sec);
if (this.Count> 2)
{
foreach (var ex in this.ToList().Skip(2))
{
binaryExpression = Expression.And(binaryExpression, Expression.Invoke(ex, par));
}
return Expression.Lambda<Func<T, bool>>(binaryExpression,par);
}
else
{
return Expression.Lambda<Func<T, bool>>(binaryExpression,par);
}
}
}
if(txtId.text != "")
criteries.Add(v => v.Id == int.Parse(txtId.text));
if(txtName.text != "")
criteries.Add(v => v.Name == txtId.text);
var finalexp = criteries.GetFinalLambdaExpression();