Csharp/C#教程:将表达式的一部分定义为c#中的变量分享


将表达式的一部分定义为c#中的变量

我有以下代码:

public class MyClass { Expression<Func> Criteria {get; set;} } public class Customer { //.. public string Name {get; set;} } 

并使用如下:

 var c = new MyClass(); c.Criteria = x.Name.StartWith("SomeTexts"); 

有没有办法定义这样的东西:

 ? p = x=>x.Customer.Name; var c = new MyClass(); c.Criteria = p => p.StartWith("SomeTexts"); 

我使用Expression<Func>将它用作我的linq to entities查询中的where子句(EF代码优先)。

您可以使用以下帮助程序函数(可以为它们提供更好的名称,但这不是必需的):

 public static class ExpressionUtils { public static Expression> Bind(this Expression> source, Expression> resultSelector) { var body = new ParameterExpressionReplacer { source = resultSelector.Parameters[0], target = source.Body }.Visit(resultSelector.Body); var lambda = Expression.Lambda>(body, source.Parameters); return lambda; } public static Expression> ApplyTo(this Expression> source, Expression> innerSelector) { return innerSelector.Bind(source); } class ParameterExpressionReplacer : ExpressionVisitor { public ParameterExpression source; public Expression target; protected override Expression VisitParameter(ParameterExpression node) { return node == source ? target : base.VisitParameter(node); } } } 

让我们看一下样本表达式

 c.Criteria = x => x.Name.StartsWith("SomeTexts"); 

可以从两个不同的部分构建。

如果你有

 Expression> e = x => x.Name; 

然后

 c.Criteria = e.Bind(x => x.StartsWith("SomeTexts")); 

或者如果你有这个

 Expression> e = x => x.StartsWith("SomeTexts"); 

然后

 c.Criteria = e.ApplyTo((Customer x) => x.Name); 

如果你有两个表达式,那么你可以使用这两个函数中的任何一个,因为a.Bind(b)相当于b.ApplyTo(a)

您必须定义类型变量explicit,但下一代码将帮助您解决您的场景:

 // define new expression that get an Order object and returns string value Expression> p = x => x.Customer.Name; var c = new MyClass(); // Compile the expression to the Func then invoke it and call extra criteria c.Criteria = o => p.Compile().Invoke(o).StartsWith("SomeText"); 

没有表达式,有一点简单的解决方案:

 Func p = x => x.Customer.Name; var c = new MyClass(); c.Criteria = o => p(o).StartsWith("SomeText"); 

您还可以在MyClass使用Func<>而不是Expression<>

 public MyClass { Func Criteria {get; set;} } 

我没有看到在这里使用Expression的好处。 一个直的Func怎么样?

 public class MyClass { public Func Criteria { get; set; } } 

然后…

 var myCustomer = new MyClass { Criteria = (c, s) => c.Name.StartsWith(s) }; var customer = new Customer { Name = "Bob" }; var x = myCustomer.Criteria(customer, "B"); 

如果需要表达式,则可以使用LinqKit执行以下操作:

 Expression> p = x => x.Name; var c = new MyClass(); c.Criteria = x => p.Invoke(x).StartsWith("asd"); //Reuse p expression c.Criteria = c.Criteria.Expand(); 

Invoke是LinqKit提供的一种扩展方法,可以帮助您轻松地编写表达式。

在调用Expand方法之后, c.Criteria将包含一个与完成此操作完全相同的表达式:

上述就是C#学习教程:将表达式的一部分定义为c#中的变量分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

 c.Criteria = x => x.Name.StartsWith("asd"); 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1009866.html

(0)
上一篇 2021年12月29日
下一篇 2021年12月29日

精彩推荐