gpt4 book ai didi

c# - 使用参数的索引器构建表达式树

转载 作者:行者123 更新时间:2023-11-30 20:54:57 24 4
gpt4 key购买 nike

给定一个具有字典属性的类

public class Product
{
public Dictionary<string, string> Attributes { get { return attributes; } }

private Dictionary<string, string> attributes = new Dictionary<string, string>();
}

我希望能够根据从数据存储中检索到的标准来匹配产品列表中的产品,这些标准的格式为

Brand == Tyco
Color != Blue

我目前的方法是从过滤器构造一个表达式,然后将该表达式作为参数传递给 LINQ Where 方法调用,如下所示

products = products.Where(myConstructedExpression);

myConstructedExpression 通常是一个看起来像的 lamda 表达式

p => p.Attributes[attribute] == value

出于测试目的,我汇编了以下代码,但无论我为 he left 表达式做了什么尝试,它总是无法调用 lambda.Compile()

Dictionary<string, ExpressionType> expressionType = new Dictionary<string, ExpressionType>();
expressionType.Add("==", ExpressionType.Equal);
expressionType.Add("!=", ExpressionType.NotEqual);

string filter = "Brand == Tyco";
string[] fields = filter.Split(' ');
string attribute = fields[0];
string op = fields[1];
string value = fields[2];

Product product = new Product();
product.Attributes.Add("Brand", "Tyco");

var parameter = Expression.Parameter(typeof(Product), "p");
var left = /***** THIS IS WHAT I AM FAILING TO CONSTRUCT PROPERLY ********/
var right = Expression.Constant(value);
var operation = Expression.MakeBinary(expressionType[op], left, right);
var lambda = Expression.Lambda<Func<Product, bool>>(operation, parameter);

var result = lambda.Compile()(product);

问题

  1. 这是否是一种合理的方法,如果是,
  2. 如何构造左边的表达式?

最佳答案

所以得到p => p.Attributes["Brand"] <someoperator> "Tyco" ,你可以做到这一点。

使用索引类型的“技巧”是使用它们的 Item属性(您也可以使用 get_item 方法)

var parameter = Expression.Parameter(typeof(Product), "p");
Expression left = Expression.Property(parameter, "Attributes");
left = Expression.Property(left, "Item", new Expression[] { Expression.Constant(attribute) });

编辑

带有 IDictionary.ContainsKey(<value>) 的版本测试

确实是一步一步来,但我认为这让事情一开始就更清楚了。

//left part of lambda, p
var parameter = Expression.Parameter(typeof(Product), "p");
//right part
//p.Attributes
Expression left = Expression.Property(parameter, "Attributes");

var method = typeof(IDictionary<string, string>).GetMethod("ContainsKey");
//p.Attributes.ContainsKey("Brand");
Expression containsExpression = Expression.Call(left, method, Expression.Constant(attribute));
//p.Attributes.Item["Brand"]
Expression keyExpression= Expression.Property(left, "Item", new Expression[] { Expression.Constant(attribute) });
//"Tyco"
var right = Expression.Constant(value);
//{p => IIF(p.Attributes.ContainsKey("Brand"), (p.Attributes.Item["Brand"] == "Tyco"), False)}
Expression operation = Expression.Condition(
containsExpression,
Expression.MakeBinary(expressionType[op], keyExpression, right),
Expression.Constant(false));
var lambda = Expression.Lambda<Func<Product, bool>>(operation, parameter);

关于c# - 使用参数的索引器构建表达式树,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18663345/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com