我有一个对象列表,我希望通过在运行时构建的表达式进行过滤。最后的表达式包含几个条件,并与&&和或者||,包含在子句中。每个条件都是这样的:
x => x.ValueType == 1 && x.Value == "abc"
如您所见,只有2个属性需要检查。
如果ValueType
为1,则Value
始终为字符串。如果ValueType
为2,则Value
应始终包含可转换为double的字符串。
属性Value
的类型为字符串。
如果条件使用大于(>)运算符,则Value
需要转换为double。
所以在这种情况下,表达式主体看起来像这样:
$x.ValueType == 2 & .Call System.Convert.ToDouble($x.Value) > 5
直到这里,一切都按预期工作。
问题:
如果我使用上面的表达式(ValueType == 2&& Value> 5)和此列表:
var list = new List<Item>();
list.Add(new Item { ValueType = 1, Value = "abc" });
list.Add(new Item { ValueType = 1, Value = "def" });
list.Add(new Item { ValueType = 2, Value = "25" });
list.Add(new Item { ValueType = 2, Value = "37" });
var results = list.AsQueryable().Where(expression);
我收到FormatException:输入字符串的格式不正确。 我以为他不会尝试将元素1和2转换为double,因为ValueType条件已经返回false。但我错了。
在将它们转换为double之前,是否需要TryParse
所有这些值,还是应该为每个值类型使用属性而不是单个字符串属性?我试图在表达式树中插入TryParse
,但我不知道如何......
将对象模型更改为多个属性会导致大量更改,这就是我想避免使用此“解决方案”的原因。
我相信,这里有人知道如何处理这个问题。或者至少可以指出我正确的方向。
答案 0 :(得分:0)
使用&&
代替&
进行C#中的短路评估。
void Main()
{
Func<Item, bool> expression = x => x.ValueType == 2 && Convert.ToDouble(x.Value) > 5;
var list = new List<Item>();
list.Add(new Item { ValueType = 1, Value = "abc" });
list.Add(new Item { ValueType = 1, Value = "def" });
list.Add(new Item { ValueType = 2, Value = "25" });
list.Add(new Item { ValueType = 2, Value = "37" });
var results = list.AsQueryable().Where(expression);
results.Dump();
}
public class Item
{
public int ValueType {get;set;}
public string Value {get;set;}
}