我想创建一个以中缀形式给出表达式的表达式树。是否需要先将表达式转换为后缀,然后再创建树?我知道这在某种程度上取决于问题本身。但假设它是带有未知数和运算符的数学函数的简单表达式,例如:/ * ^ + -。
infix-notation expression-trees postfix-notation data-structures
我想为此动态创建一个 lambda 表达式:
(o => o.Year == year && o.CityCode == cityCode && o.Status == status)
Run Code Online (Sandbox Code Playgroud)
我这样写:
var body = Expression.AndAlso(
Expression.Equal(
Expression.PropertyOrField(param, "Year"),
Expression.Constant(year)
),
Expression.Equal(
Expression.PropertyOrField(param, "CityCode"),
Expression.Constant(cityCode)
)
,
Expression.Equal(
Expression.PropertyOrField(param, "Status"),
Expression.Constant(status)
)
);
Run Code Online (Sandbox Code Playgroud)
但对于这段代码:
Expression.Equal(
Expression.PropertyOrField(param, "Status"),
Expression.Constant(status)
)
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
无法从“System.Linq.Expressions.BinaryExpression”转换为“System.Reflection.MethodInfo”
如何向 lambda 表达式添加 3 个条件?
我一直在使用表达式树的 EF Core 查询的动态过滤器类中工作,一切看起来都很好,过滤器正在工作,我可以传递一个过滤器集合并且它可以工作,但是当我查看 SQL 语句时,它正在查询整个表并对结果集合应用过滤器,这是我的课程......
public static class QueryExpressionBuilder
{
private static readonly MethodInfo ContainsMethod = typeof(string).GetMethod("Contains", new[] { typeof(string) });
private static readonly MethodInfo StartsWithMethod = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
private static readonly MethodInfo EndsWithMethod = typeof(string).GetMethod("EndsWith", new[] { typeof(string) });
#region DynamicWhere
/// <summary>Where expression generator.</summary>
/// <typeparam name="T"></typeparam>
/// <param name="filters">The filters.</param>
/// <returns></returns>
public static Expression<Func<T, bool>> GetExpression<T>(IList<Filter> filters)
{
if (filters.Count == 0)
return null;
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Expression exp = …Run Code Online (Sandbox Code Playgroud) 是否有可能在.NET中遍历Expression实例?
我的意思是:我在外部代码中生成了Expression/Expresstion>实例.有没有可能看到那里有什么?
我正在尝试解决的现实世界问题:我有一个数据库,其中一堆电话号码以绝对可怕的格式存储为字符串(例如"(02)9971 1209").我的程序的用户将开始输入电话号码,当他输入时,他将输入的内容将被发送并用于使用"startswith"操作过滤数据库中的电话号码列表.
问题是,如果用户键入"02997",它将不会匹配任何内容,因为数字与位于括号中的位置代码一起存储.为了使此操作起作用,用户必须通过键入'(')来开始每次搜索.这不好.
tl;问题底部的博士版本
我把这个问题从它的真实世界环境中解决出来,变成了一个更小,更密集的解决方案,我可以专注于它而不会分散大量的代码库.在这种情况下,我的解决方案是做一些linq棘手:
class Program
{
static string [] phones = {"(02) 9489 3048","(04) 1128 2148","(01) 9971 1208",};
static void Main(string[] args)
{
for (;;)
{
Console.WriteLine("Enter your number: ");
string input = Console.ReadLine();
Func<string, string> strip =
tehstring => tehstring.Where(x => char.IsDigit(x))
.Aggregate("", (x, y) => x + y);
var results = phones.Where(z => strip(z).StartsWith(strip(input)));
foreach (var x in results)
Console.WriteLine(x);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这一切都很好,效果很好,完全符合我的需要.但它只适用于这个孤立的上下文:我无法将其移回需要实现的代码库,因为我需要将其转换为表达式树.
我需要解决的代码:
static Expression GetOperationExpression(
StringFilterOperation operation,
Expression propertyExpression,
Expression valueExpression)
{
switch …Run Code Online (Sandbox Code Playgroud) 我有以下声明.
var search = PredicateBuilder.True<SomeType>();
search.And(f => false);
// Still the "search" variable value is: {f => true}.
Run Code Online (Sandbox Code Playgroud)
起初,我正在尝试表达; 没有成功,所以我尝试了这个"假".不管我做了什么,它仍然是一样的.怎么了?
我得到一个包含运算符+, - ,*,/和括号的算术公式(可能会也可能不会改变运算符的自然优先级).一个例子如下:a/b + f - (c + d)*e - a*c.并且我被要求使用堆栈(实现为链接列表)以跟踪操作数和运算符:我的程序应该如何工作的示例如下:
我难以理解的问题是如何区分操作数的优先级!
这是我写的代码的不完整版本:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
typedef struct btnode Btree;
typedef struct node s_Node;
struct btnode {
char info;
Btree *left;
Btree *right;
};
struct node {
char element;
s_Node*next;
};
typedef struct{
s_Node *top_stack;
} stack_t;
int IsOperator(char c);
main () {
FILE* fp;
stack_t …Run Code Online (Sandbox Code Playgroud) 我最近发布了一个关于如何编写自定义表达式树的问题(虽然我没有意识到那是我当时要求的).现在我试图使用Scott Chamberlain提供的答案来创建另一种通用方法.
我正在使用Entity Framework并且有几个实体可以通过"Name"属性进行过滤.它并不总是名为Name,但基本上就是它.
实际的过滤方法比简单的包含或开始更复杂.它更像是一个Starts With,然后将包含搜索文本的名称的任何记录追加到列表的末尾.
由于有太多实体需要执行此过滤器,我希望能够创建一个将该过滤器应用于预编译查询的扩展方法.
我想能打电话
someQuery.ContainsName(x => x.Name, filter.Name);
Run Code Online (Sandbox Code Playgroud)
我有一个看起来像这样的扩展方法
public static IQueryable<T> ContainsName<T>(this IQueryable<T> query, Expression<Func<T, string>> selector, string matchingName)
{
var name = Expression.Constant(matchingName);
var selectorBody = selector.Body;
var propertyName = (selectorBody as MemberExpression).Member.Name;
var propExpression = Expression.Parameter(typeof(string), propertyName);
var selectorParameters = selector.Parameters;
Expression check = Expression.Call(typeof(GenericNameFilter).GetMethod("IsMatch"), propExpression, name);
var lambada = Expression.Lambda<Func<T, bool>>(check, selectorParameters);
return query.Where(lambada)
}
Run Code Online (Sandbox Code Playgroud)
IsMatch只接受2个字符串并返回一个bool.这不是该方法的最终游戏,但我希望能够让IsMatch的简单版本正常工作,然后我会扩展它.
当我在结果上调用ToList时,我得到一个例外.
"LINQ to Entities无法识别方法'Boolean IsMatch(System.String,System.String)'方法,并且此方法无法转换为商店表达式."
从我所做的搜索中我相信我想要做的事情是可能的,我只是做错了.这是我设置表达式树的方式吗?是IsMatch方法吗?一切都是错的吗?
我正在尝试用linq实现表达式树.我正在获取错误状态,因为无法将lambdaexpression转换为表达式.请帮助我检查其他解决方案,但无法帮助!以下是我的代码
ParameterExpression pe = Expression.Parameter(typeof(Person), "p");
var expr = Expression.Lambda(Expression.Property(pe, sortByProp), pe);
var d= expr.Compile();
IQueryable<Person> query = persons.AsQueryable();
List<Person> sortedList = query.OrderBy<Person, int>(expr).ToList();
Run Code Online (Sandbox Code Playgroud) expression-trees ×10
c# ×8
linq ×5
.net ×2
binary-tree ×1
c ×1
c#-4.0 ×1
ef-core-2.1 ×1
lambda ×1
stack ×1
traversal ×1